Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Matplotlib FuncAnimation.save() only saves 100 frames

I am trying to save an animation I've created with the FuncAnimation class in Matplotlib. My animation is more complicated, but I get the same error when I try to save the simple example given here.

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation

pause = False
def simData():
    t_max = 10.0
    dt = 0.05
    x = 0.0
    t = 0.0
    while t < t_max:
        if not pause:
            x = np.sin(np.pi*t)
            t = t + dt
        yield x, t

def onClick(event):
    global pause
    pause ^= True

def simPoints(simData):
    x, t = simData[0], simData[1]
    time_text.set_text(time_template%(t))
    line.set_data(t, x)
    return line, time_text

fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([], [], 'bo', ms=10) # I'm still not clear on this stucture...
ax.set_ylim(-1, 1)
ax.set_xlim(0, 10)

time_template = 'Time = %.1f s'    # prints running simulation time
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
fig.canvas.mpl_connect('button_press_event', onClick)
ani = animation.FuncAnimation(fig, simPoints, simData, blit=False, interval=10,
    repeat=True)
plt.show()

However, when I try to save this animation by adding the line

ani.save('test.mp4')

at the end, only the first 100 frames are saved.

After the animation is saved, the function restarts and displays as expected, displaying and updating the figure 200 times (or until t reaches t_max, whatever I set that to be). But the movie that is saved only contains the first 100 frames.

The pause functionality makes it tricky. Without it I could just put in frames = 200 into the FuncAnimation call rather that using the iterator/generator type function I currently have for the frames argument. But by just putting in frames = 200, the frame count seems to be un-pauseable.

How can I fix this?

like image 763
hm8 Avatar asked Aug 16 '16 17:08

hm8


People also ask

How do I save a Matplotlib animation?

To save an animation, we can use Animation. save() or Animation.

What is interval in FuncAnimation?

interval: It is an optional integer value that represents the delay between each frame in milliseconds. Its default is 100. repeat_delay: It is an optional integer value that adds a delay in milliseconds before repeating the animation. It defaults to None.

What is Blit in FuncAnimation?

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) plt.show()

How do I stop func animation?

Alternatively you may stop the animation with anim. event_source. stop() . In order to have access to the animation inside the animating function one may use a class and make the animation a class variable.


1 Answers

ani = animation.FuncAnimation(fig, simPoints, simData, blit=False, interval=10,
                              repeat=True, save_count=200)  

will solve the ploblem.

Internally, save only saves a fixed number of frames. If you pass in a fixed length sequence or a number, mpl can correctly guess the length. If you pass in a (possibly infinite) generator and do not pass in save_count it defaults to 100.

like image 93
tacaswell Avatar answered Oct 20 '22 15:10

tacaswell