Skip to content
Advertisement

Animating two circles Python

I have a text file, with the coordinates of two circles on it. I want to produce a live animation of both particles. For some reason the following code crashes

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import pandas as pd

df = pd.read_csv('/path/to/text/file.txt', sep=" ", header=None)

fig = plt.figure()
fig.set_dpi(100)
fig.set_size_inches(7, 6.5)

ax = plt.axes(xlim=(0, 60), ylim=(0, 60))
patch = plt.Circle((5, -5), 6, fc='y')
patch2 = plt.Circle((5, -5), 6, fc='y')

def init():
    patch.center = (df[0][0], df[1][0])
    patch2.center = (df[2][0], df[3][0])
    ax.add_patch(patch)
    return patch, patch2,

def animate(i):
    x, y = patch.center
    x2, y2 = patch2.center
    x = df[0][i]
    y = df[1][i]
    x2 = df[2][i]
    y2 = df[3][i]
    patch.center = (x, y)
    patch2.center = (x2, y2)
    i += 1
    return patch, patch2,

anim = animation.FuncAnimation(fig, animate,
                               init_func=init,
                               frames=360,
                               interval=20,
                               blit=True)
plt.show()

The text file that the data is taken from has the columns of X1, Y1, X2 and Y2 where X1 represents the x coordinate of the 1st particle etc.

If I remove all references to the second particle, it works and fully displays the first. Any help would be appreciated.

An example of the text file is the following:

40.028255 30.003469 29.999967 20.042583 29.999279 29.997491 
40.073644 30.001855 30.000070 20.090549 30.002644 29.997258 
40.135379 29.996389 29.995906 20.145826 30.005277 29.997931 
40.210547 29.998941 29.996237 20.197438 30.004859 30.002082 
40.293916 30.002021 29.992079 20.248248 29.998585 30.006919

(The latter columns arent used in this code) and the exact error message is ‘AttributeError: ‘NoneType’ object has no attribute ‘_get_view”.

Thank you

Advertisement

Answer

The code crashes because you “mixed” matplotlib’s “pyplot” and “object-oriented” approaches in a wrong way. Here is the working code. Note that I created ax, the axes in which artists are going to be added. On this axes I also applied the axis limits.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.patches import Circle

N = 360
df = pd.DataFrame({
    "x1": np.linspace(0, 60, N),
    "y1": np.linspace(0, 60, N),
    "x2": np.flip(np.linspace(0, 60, N)),
    "y2": np.linspace(0, 60, N),
})

fig = plt.figure()
ax = fig.add_subplot()

ax.set_xlim(0, 60)
ax.set_ylim(0, 60)

patch = Circle((5, -5), 6, fc='y')
patch2 = Circle((5, -5), 6, fc='y')
ax.add_artist(patch)
ax.add_artist(patch2)

def init():
    patch.center = (df["x1"][0], df["y1"][0])
    patch2.center = (df["x2"][0], df["y2"][0])
    return patch, patch2

def animate(i):
    x, y = patch.center
    x2, y2 = patch2.center
    x = df["x1"][i]
    y = df["y1"][i]
    x2 = df["x2"][i]
    y2 = df["y2"][i]
    patch.center = (x, y)
    patch2.center = (x2, y2)
    i += 1
    return patch, patch2,

anim = animation.FuncAnimation(fig, animate,
                               init_func=init,
                               frames=N,
                               interval=20,
                               blit=True)
plt.show()
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement