I'm working on a script that moves a vertical line along an x-axis, over a series of datapoints. The animation works fine with plt.show
but I am having trouble outputting a movie file. Please be aware that I am very new to Python, though I've been playing around with it for a year or two. The script was created by combining the first script in this tutorial with the script presented in the answer to this previous stack overflow question. The line will eventually be moving over a static data line chart, which I am presenting here as a diagonal line.
The movie file is output as having the correct length of time (1min, 10sec), but the line, which should move from the far left to the far right, 1-point per second, only moves a few pixels in the output video.
Any help you may be able to provide to solve this problem would be greatly appreciated.
Edit: I'm running Python 2.7.6 on Ubuntu 14.04.
Here is my reproducible code:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import time
# Simulated background data
x = np.linspace(0,61,62)
y = np.linspace(0,6,62)
# Set up the figure, the axis, and the plot element we want to animate
max_height = 6 # max height of y-axis
n_pts = 61 # max length of x-axis
# Original location for progress line
y1 = [0, max_height]
x1 = [0, 0]
fig = plt.figure() # Initialize figure
#ax = fig.add_subplot(111) # Intialize axes
ax = plt.axes(xlim=(0, n_pts), ylim=(0, max_height)) # Set axes limits
line, = ax.plot([], [], lw=2) # Initialize line
# draw the data to the 'background'
line1, = ax.plot(x, y, color='black')
# initialization function: plot the background of each frame
def init():
line.set_data(x1, y1)
return line,
starttime=time.time()
mytimer=0
mytimer_ref=0
# animation function. This is called sequentially
def animate(i):
t = time.time() - starttime
mytimer = t + mytimer_ref
x1 = [mytimer,mytimer]
line.set_data(x1, y1)
return line,
# call the animator.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=61, interval=1000)
# save the animation as an mp4. This requires ffmpeg or mencoder to be
# installed. The extra_args ensure that the x264 codec is used, so that
# the video can be embedded in html5. You may need to adjust this for
# your system: for more information, see
# http://matplotlib.sourceforge.net/api/animation_api.html
writer = animation.writers['ffmpeg'](fps=1)
anim.save('demo.mp4',writer=writer,dpi=dpi)
plt.show()
Edit The following script creates the movie and saves it as an mp4. The problem now is that though there are 61 frames of animation, I can't get the movie to stop there. It proceeds to 100 frames every time. I know this question is a bit old now, but any help is greatly appreciated!
I have attempted to manually set the x-axis, which limits what is shown on the screen, but the animation continues beyond the shown axis nonetheless.
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from time import time
from scipy.interpolate import interp1d
max_height = 6 # max height of y-axis
n_pts = 62 # max length of x-axis
x = np.linspace(0,61,62)
y = np.linspace(0,6,62)
# New figure with white background
fig = plt.figure(facecolor = 'white')
ax = plt.axes(aspect=1) # Set axes limits
# Original location for progress line
y1 = [0, max_height]
x1 = [0, 0]
# initialize line
plt.plot(x, y) #plot background
line, = ax.plot([], [], lw=2)
def update(frame):
x1 = frame
line.set_data(x1, y1)
# Return the modified line
return line,
anim = animation.FuncAnimation(fig, update, interval=1000, blit=True)
anim.save('line.mp4', writer='ffmpeg')
plt.show()
For your edited code, include two additional arguments in the call to
animation.FuncAnimation
:frames=25
(25
chosen as an example) - set the max number of frames againrepeat=False
- do not repeat the animation after the max number of framesCombined, you get this command:
This results in a animation which steps through 25 frames (in your case, moves the vertical line from
0
to24
in one second intervals) - and stops there.