Animations are generated from a list (or other iterable) of graphics objects. Images are produced by calling the save_image method on each input object, and using ImageMagick’s convert program [IM] or ffmpeg [FF] to generate an animation. The output format is GIF by default, but can be any of the formats supported by convert or ffmpeg.
Warning
Note that ImageMagick and FFmpeg are not included with Sage, and must be installed by the user. On unix systems, type which convert at a command prompt to see if convert (part of the ImageMagick suite) is installed. If it is, you will be given its location. Similarly, you can check for ffmpeg with which ffmpeg. See [IM] or [FF] for installation instructions.
EXAMPLES:
The sine function:
sage: sines = [plot(c*sin(x), (-2*pi,2*pi), color=Color(c,0,0), ymin=-1,ymax=1) for c in sxrange(0,1,.2)]
sage: a = animate(sines)
sage: a
Animation with 5 frames
sage: a.show() # optional -- ImageMagick
Animate using ffmpeg instead of ImageMagick:
sage: f = tmp_filename(ext='.gif')
sage: a.save(filename=f,use_ffmpeg=True) # optional -- ffmpeg
An animated sage.plot.graphics.GraphicsArray of rotating ellipses:
sage: E = animate((graphics_array([[ellipse((0,0),a,b,angle=t,xmin=-3,xmax=3)+circle((0,0),3,color='blue') for a in range(1,3)] for b in range(2,4)]) for t in sxrange(0,pi/4,.15)))
sage: E # animations produced from a generator do not have a known length
Animation with unknown number of frames
sage: E.show() # optional -- ImageMagick
A simple animation of a circle shooting up to the right:
sage: c = animate([circle((i,i), 1-1/(i+1), hue=i/10) for i in srange(0,2,0.2)],
....: xmin=0,ymin=0,xmax=2,ymax=2,figsize=[2,2])
sage: c.show() # optional -- ImageMagick
Animations of 3d objects:
sage: var('s,t')
(s, t)
sage: def sphere_and_plane(x):
....: return sphere((0,0,0),1,color='red',opacity=.5)+parametric_plot3d([t,x,s],(s,-1,1),(t,-1,1),color='green',opacity=.7)
sage: sp = animate([sphere_and_plane(x) for x in sxrange(-1,1,.3)])
sage: sp[0] # first frame
sage: sp[-1] # last frame
sage: sp.show() # optional -- ImageMagick
sage: (x,y,z) = var('x,y,z')
sage: def frame(t):
....: return implicit_plot3d((x^2 + y^2 + z^2), (x, -2, 2), (y, -2, 2), (z, -2, 2), plot_points=60, contour=[1,3,5], region=lambda x,y,z: x<=t or y>=t or z<=t)
sage: a = animate([frame(t) for t in srange(.01,1.5,.2)])
sage: a[0] # first frame
sage: a.show() # optional -- ImageMagick
If the input objects do not have a save_image method, then the animation object attempts to make an image by calling its internal method sage.plot.animate.Animation.make_image(). This is illustrated by the following example:
sage: t = var('t')
sage: a = animate((sin(c*pi*t) for c in sxrange(1,2,.2)))
sage: a.show() # optional -- ImageMagick
AUTHORS:
REFERENCES:
[IM] | http://www.imagemagick.org |
[FF] | http://www.ffmpeg.org |
Bases: sage.structure.sage_object.SageObject
Return an animation of a sequence of plots of objects.
INPUT:
EXAMPLES:
sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.3)],
....: xmin=0, xmax=2*pi, figsize=[2,1])
sage: a
Animation with 21 frames
sage: a[:5]
Animation with 5 frames
sage: a.show() # optional -- ImageMagick
sage: a[:5].show() # optional -- ImageMagick
The show() method takes arguments to specify the delay between frames (measured in hundredths of a second, default value 20) and the number of iterations (default value 0, which means to iterate forever). To iterate 4 times with half a second between each frame:
sage: a.show(delay=50, iterations=4) # optional -- ImageMagick
An animation of drawing a parabola:
sage: step = 0.1
sage: L = Graphics()
sage: v = []
sage: for i in srange(0,1,step):
....: L += line([(i,i^2),(i+step,(i+step)^2)], rgbcolor=(1,0,0), thickness=2)
....: v.append(L)
sage: a = animate(v, xmin=0, ymin=0)
sage: a.show() # optional -- ImageMagick
sage: show(L)
TESTS:
This illustrates that trac ticket #2066 is fixed (setting axes ranges when an endpoint is 0):
sage: animate([plot(sin, -1,1)], xmin=0, ymin=0)._kwds['xmin']
0
We check that trac ticket #7981 is fixed:
sage: a = animate([plot(sin(x + float(k)), (0, 2*pi), ymin=-5, ymax=5)
....: for k in srange(0,2*pi,0.3)])
sage: a.show() # optional -- ImageMagick
Do not convert input iterator to a list:
sage: a = animate((x^p for p in sxrange(1,2,.1))); a
Animation with unknown number of frames
sage: a._frames
<generator object ...
Returns a movie showing an animation composed from rendering the frames in self.
This method will only work if ffmpeg is installed. See http://www.ffmpeg.org for information about ffmpeg.
INPUT:
If savefile is not specified: in notebook mode, display the animation; otherwise, save it to a default file name. Use sage.misc.misc.set_verbose() with level=1 to see additional output.
EXAMPLES:
sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)],
....: xmin=0, xmax=2*pi, figsize=[2,1])
sage: dir = tmp_dir()
sage: a.ffmpeg(savefile=dir + 'new.mpg') # optional -- ffmpeg
sage: a.ffmpeg(savefile=dir + 'new.avi') # optional -- ffmpeg
sage: a.ffmpeg(savefile=dir + 'new.gif') # optional -- ffmpeg
sage: a.ffmpeg(savefile=dir + 'new.mpg', show_path=True) # optional -- ffmpeg
Animation saved to .../new.mpg.
Note
If ffmpeg is not installed, you will get an error message like this:
Error: ffmpeg does not appear to be installed. Saving an animation to
a movie file in any format other than GIF requires this software, so
please install it and try again.
See www.ffmpeg.org for more information.
TESTS:
sage: a.ffmpeg(output_format='gif',delay=30,iterations=5) # optional -- ffmpeg
Returns an animated gif composed from rendering the graphics objects in self.
This method will only work if either (a) the ImageMagick software suite is installed, i.e., you have the convert command or (b) ffmpeg is installed. See [IM] for more about ImageMagick, and see [FF] for more about ffmpeg. By default, this produces the gif using convert if it is present. If this can’t find convert or if use_ffmpeg is True, then it uses ffmpeg instead.
INPUT:
If savefile is not specified: in notebook mode, display the animation; otherwise, save it to a default file name.
EXAMPLES:
sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)],
....: xmin=0, xmax=2*pi, figsize=[2,1])
sage: dir = tmp_dir()
sage: a.gif() # not tested
sage: a.gif(savefile=dir + 'my_animation.gif', delay=35, iterations=3) # optional -- ImageMagick
sage: a.gif(savefile=dir + 'my_animation.gif', show_path=True) # optional -- ImageMagick
Animation saved to .../my_animation.gif.
sage: a.gif(savefile=dir + 'my_animation_2.gif', show_path=True, use_ffmpeg=True) # optional -- ffmpeg
Animation saved to .../my_animation_2.gif.
Note
If neither ffmpeg nor ImageMagick is installed, you will get an error message like this:
Error: Neither ImageMagick nor ffmpeg appears to be installed. Saving an
animation to a GIF file or displaying an animation requires one of these
packages, so please install one of them and try again.
See www.imagemagick.org and www.ffmpeg.org for more information.
Return a sage.plot.graphics.GraphicsArray with plots of the frames of this animation, using the given number of columns. The frames must be acceptable inputs for sage.plot.graphics.GraphicsArray.
EXAMPLES:
sage: E = EllipticCurve('37a')
sage: v = [E.change_ring(GF(p)).plot(pointsize=30) for p in [97, 101, 103, 107]]
sage: a = animate(v, xmin=0, ymin=0)
sage: a
Animation with 4 frames
sage: a.show() # optional -- ImageMagick
Modify the default arrangement of array:
sage: g = a.graphics_array(); print g
Graphics Array of size 2 x 3
sage: g.show(figsize=[4,1]) # optional
Specify different arrangement of array and save with different file name:
sage: g = a.graphics_array(ncols=2); print g
Graphics Array of size 2 x 2
sage: f = tmp_filename(ext='.png')
sage: g.show(f) # optional
Frames can be specified as a generator too; it is internally converted to a list:
sage: t = var('t')
sage: b = animate((plot(sin(c*pi*t)) for c in sxrange(1,2,.2)))
sage: g = b.graphics_array(); print g
Graphics Array of size 2 x 3
sage: g.show() # optional
Given a frame which has no save_image() method, make a graphics object and save it as an image with the given filename. By default, this is sage.plot.plot.plot(). To make animations of other objects, override this method in a subclass.
EXAMPLES:
sage: from sage.plot.animate import Animation
sage: class MyAnimation(Animation):
....: def make_image(self, frame, filename, **kwds):
....: P = parametric_plot(frame[0], frame[1], **frame[2])
....: P.save_image(filename,**kwds)
sage: t = var('t')
sage: x = lambda t: cos(t)
sage: y = lambda n,t: sin(t)/n
sage: B = MyAnimation([([x(t), y(i+1,t)],(t,0,1), {'color':Color((1,0,i/4)), 'aspect_ratio':1, 'ymax':1}) for i in range(4)])
sage: d = B.png()
sage: v = os.listdir(d); v.sort(); v
['00000000.png', '00000001.png', '00000002.png', '00000003.png']
sage: B.show() # not tested
sage: class MyAnimation(Animation):
....: def make_image(self, frame, filename, **kwds):
....: G = frame.plot()
....: G.set_axes_range(floor(G.xmin()),ceil(G.xmax()),floor(G.ymin()),ceil(G.ymax()))
....: G.save_image(filename, **kwds)
sage: B = MyAnimation([graphs.CompleteGraph(n) for n in range(7,11)], figsize=5)
sage: d = B.png()
sage: v = os.listdir(d); v.sort(); v
['00000000.png', '00000001.png', '00000002.png', '00000003.png']
sage: B.show() # not tested
Render PNG images of the frames in this animation, saving them in dir. Return the absolute path to that directory. If the frames have been previously rendered and dir is None, just return the directory in which they are stored.
When dir is other than None, force re-rendering of frames.
INPUT:
EXAMPLES:
sage: a = animate([plot(x^2 + n) for n in range(4)])
sage: d = a.png()
sage: v = os.listdir(d); v.sort(); v
['00000000.png', '00000001.png', '00000002.png', '00000003.png']
Save this animation.
INPUT:
If filename is None, then in notebook mode, display the animation; otherwise, save the animation to a GIF file. If filename ends in ‘.sobj’, save to an sobj file. Otherwise, try to determine the format from the filename extension (‘.mpg’, ‘.gif’, ‘.avi’, etc.). If the format cannot be determined, default to GIF.
For GIF files, either ffmpeg or the ImageMagick suite must be installed. For other movie formats, ffmpeg must be installed. An sobj file can be saved with no extra software installed.
EXAMPLES:
sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)],
....: xmin=0, xmax=2*pi, figsize=[2,1])
sage: dir = tmp_dir()
sage: a.save() # not tested
sage: a.save(dir + 'wave.gif') # optional -- ImageMagick
sage: a.save(dir + 'wave.gif', show_path=True) # optional -- ImageMagick
Animation saved to file .../wave.gif.
sage: a.save(dir + 'wave.avi', show_path=True) # optional -- ffmpeg
Animation saved to file .../wave.avi.
sage: a.save(dir + 'wave0.sobj')
sage: a.save(dir + 'wave1.sobj', show_path=True)
Animation saved to file .../wave1.sobj.
Show this animation.
INPUT:
Note
Currently this is done using an animated gif, though this could change in the future. This requires that either ffmpeg or the ImageMagick suite (in particular, the convert command) is installed.
See also the ffmpeg() method.
EXAMPLES:
sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)],
....: xmin=0, xmax=2*pi, figsize=[2,1])
sage: a.show() # optional -- ImageMagick
The preceding will loop the animation forever. If you want to show only three iterations instead:
sage: a.show(iterations=3) # optional -- ImageMagick
To put a half-second delay between frames:
sage: a.show(delay=50) # optional -- ImageMagick
Note
If you don’t have ffmpeg or ImageMagick installed, you will get an error message like this:
Error: Neither ImageMagick nor ffmpeg appears to be installed. Saving an
animation to a GIF file or displaying an animation requires one of these
packages, so please install one of them and try again.
See www.imagemagick.org and www.ffmpeg.org for more information.
Animate a list of frames by creating a sage.plot.animate.Animation object.
EXAMPLES:
sage: t = var('t')
sage: a = animate((cos(c*pi*t) for c in sxrange(1,2,.2)))
sage: a.show() # optional -- ImageMagick