I'm using the FuncAnimation package to make a movie of a gaussian wavepacket colliding with a potential barrier using the finite difference real-space method for solving the Schrodinger equation. The relevant code is below. Basically, when I run it, everything works well - a movie pops up showing just what I want. However, changing the "frames=" argument does not actually alter the number of frames. You can see that I print the current iteration in my animate function. This counter goes up to the number specified in "frames=", but then goes back to 0 and keeps going. The animation runs farther than specified. Even if I specify "frames=1", the movie will continue indefinitely (I tried leaving it running for an afternoon). I'm pretty stumped as to what's going on but I'm relatively sure it's something stupid.
# Set up the matplotlib figure and axes
fig = plt.figure()
ax = plt.axes(xlim = (0, hamiltonian.L), ylim = (0, 3))
line, = ax.plot([], [], lw = 2)
time_text = ax.text(.02, .95, '', transform=ax.transAxes)
ax.grid()
def init():
"""initialize the animation"""
line.set_data([], [])
time_text.set_text('')
return line, time_text
def animate(i):
"""actually perform the animation"""
print i
global hamiltonian, wavepacket
hamiltonian.propagate(wavepacket)
line.set_data(wavepacket.x, wavepacket.psi_sq)
time_text.set_text('time = %.3f' % wavepacket.time_elapsed)
return line, time_text
# Now call the animator
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=1, blit=False)
#anim.save('gaussian_reflection.mp4', fps=150, extra_args=['-vcodec', 'libx264'])
plt.show()
If the blit value is equal to True then, func returns an iterable of all artists that are to be modified or created. This data is used by the blitting algorithm to decide which parts of the figure has to be updated. If blit== False then the value returned is unused or omitted.
Makes an animation by repeatedly calling a function func. The figure object that is used to get draw, resize, and any other needed events. The function to call at each frame.
pi * (x - 0.01 * i)) line. set_data(x, y) return line, # call the animator. blit=True means only re-draw the parts that have changed. anim = animation. FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True) # save the animation as an mp4.
using the Animation. pause() method to pause an animation.
By default the animation function loops, just use the repeat
kwarg:
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=100, interval=1, blit=False, repeat=False)
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