I am trying to test a Matplotlib animation example on my jupyter notebook which is listed as following:
from matplotlib import animation
# solve the ode problem of the double compound pendulum again
from scipy.integrate import odeint
from numpy import cos, sin
g = 9.82; L = 0.5; m = 0.1
def dx(x, t):
x1, x2, x3, x4 = x[0], x[1], x[2], x[3]
dx1 = 6.0/(m*L**2) * (2 * x3 - 3 * cos(x1-x2) * x4)/(16 - 9 * cos(x1-x2)**2)
dx2 = 6.0/(m*L**2) * (8 * x4 - 3 * cos(x1-x2) * x3)/(16 - 9 * cos(x1-x2)**2)
dx3 = -0.5 * m * L**2 * ( dx1 * dx2 * sin(x1-x2) + 3 * (g/L) * sin(x1))
dx4 = -0.5 * m * L**2 * (-dx1 * dx2 * sin(x1-x2) + (g/L) * sin(x2))
return [dx1, dx2, dx3, dx4]
x0 = [np.pi/2, np.pi/2, 0, 0] # initial state
t = np.linspace(0, 10, 250) # time coordinates
x = odeint(dx, x0, t) # solve the ODE problem
fig, ax = plt.subplots(figsize=(5,5))
ax.set_ylim([-1.5, 0.5])
ax.set_xlim([1, -1])
pendulum1, = ax.plot([], [], color="red", lw=2)
pendulum2, = ax.plot([], [], color="blue", lw=2)
def init():
pendulum1.set_data([], [])
pendulum2.set_data([], [])
def update(n):
# n = frame counter
# calculate the positions of the pendulums
x1 = + L * sin(x[n, 0])
y1 = - L * cos(x[n, 0])
x2 = x1 + L * sin(x[n, 1])
y2 = y1 - L * cos(x[n, 1])
# update the line data
pendulum1.set_data([0 ,x1], [0 ,y1])
pendulum2.set_data([x1,x2], [y1,y2])
anim = animation.FuncAnimation(fig, update, init_func=init, frames=len(t), blit=True)
# anim.save can be called in a few different ways, some which might or might not work
# on different platforms and with different versions of matplotlib and video encoders
#anim.save('animation.mp4', fps=20, extra_args=['-vcodec', 'libx264'], writer=animation.FFMpegWriter())
#anim.save('animation.mp4', fps=20, extra_args=['-vcodec', 'libx264'])
#anim.save('animation.mp4', fps=20, writer="ffmpeg", codec="libx264")
anim.save('animation.mp4', fps=20, writer="avconv", codec="libx264")
plt.close(fig)
However, when I run the cell in notebook it gives me this error:
RuntimeError: The init_func must return a sequence of Artist objects.
I am not quite sure what is going on.. I don't see anything wrong in the init function.
The link to this example: https://github.com/jrjohansson/scientific-python-lectures/blob/master/Lecture-4-Matplotlib.ipynb It is at the very bottom of this notebook.
As the error suggests, and as can be seen e.g. in the simple_animation example, but also from the FuncAnimation
documentation, the init_func
as well as the updating func
are supposed to return an iterable of artists to animate.
The documentation does not say that this is actually only needed when using blit=True
, but since you are using blitting here, it is definitely needed.
What you would therefore need to do is to let the init
function as well as the update
function return the two lines which get animated
def init():
pendulum1.set_data([], [])
pendulum2.set_data([], [])
return pendulum1, pendulum2,
def update(n):
# n = frame counter
# calculate the positions of the pendulums
x1 = + L * sin(x[n, 0])
y1 = - L * cos(x[n, 0])
x2 = x1 + L * sin(x[n, 1])
y2 = y1 - L * cos(x[n, 1])
# update the line data
pendulum1.set_data([0 ,x1], [0 ,y1])
pendulum2.set_data([x1,x2], [y1,y2])
return pendulum1, pendulum2,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With