### Navigation

- index
- modules |
- next |
- previous |
- 2D Graphics »

# Animated plots

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
    Graphics3d Object
    sage: sp[-1]     # last frame
    Graphics3d Object
    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
    Graphics3d Object
    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:

- William Stein
- John Palmieri
- Niles Johnson (2013-12): Expand to animate more graphics objects

REFERENCES:

[IM] | http://www.imagemagick.org

[FF] | http://www.ffmpeg.org

class `sage.plot.animate.``Animation`(v=None, **kwds)

  Bases: `sage.structure.sage_object.SageObject`

  Return an animation of a sequence of plots of objects.

  INPUT:

  - `v` - iterable of Sage objects. These should preferably be graphics objects, but if they aren’t then `make_image()` is called on them.
  - `xmin, xmax, ymin, ymax` - the ranges of the x and y axes.
  - `**kwds` - all additional inputs are passed onto the rendering command. E.g., use figsize to adjust the resolution and aspect ratio.

  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 ...

  `ffmpeg`(savefile=None, show_path=False, output_format=None, ffmpeg_options='', delay=None, iterations=0, pix_fmt='rgb24')

    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:

    - `savefile` - file that the mpeg gets saved to.
    - `show_path` - boolean (default: False); if True, print the path to the saved file
    - `output_format` - string (default: None); format and suffix to use for the video. This may be ‘mpg’, ‘mpeg’, ‘avi’, ‘gif’, or any other format that ffmpeg can handle. If this is None and the user specifies `savefile` with a suffix, say `savefile='animation.avi'`, try to determine the format (‘avi’ in this case) from that file name. If no file is specified or if the suffix cannot be determined, ‘mpg’ is used.
    - `ffmpeg_options` - string (default: ‘’); this string is passed directly to ffmpeg.
    - `delay` - integer (default: None); delay in hundredths of a second between frames. The framerate is 100/delay. This is not supported for mpeg files: for mpegs, the frame rate is always 25 fps.
    - `iterations` - integer (default: 0); number of iterations of animation. If 0, loop forever. This is only supported for animated gif output and requires ffmpeg version 0.9 or later. For older versions, set `iterations=None`.
    - `pix_fmt` - string (default: ‘rgb24’); used only for gif output. Different values such as ‘rgb8’ or ‘pal8’ may be necessary depending on how ffmpeg was installed. Set `pix_fmt=None` to disable this option.

    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

  `gif`(delay=20, savefile=None, iterations=0, show_path=False, use_ffmpeg=False)

    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:

    - `delay` - (default: 20) delay in hundredths of a second between frames
    - `savefile` - file that the animated gif gets saved to
    - `iterations` - integer (default: 0); number of iterations of animation. If 0, loop forever.
    - `show_path` - boolean (default: False); if True, print the path to the saved file
    - `use_ffmpeg` - boolean (default: False); if True, use ‘ffmpeg’ by default instead of ‘convert’.

    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.

  `graphics_array`(ncols=3)

    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

  `make_image`(frame, filename, **kwds)

    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

  `png`(dir=None)

    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:

    - `dir` – Directory in which to store frames. Default `None`; in this case, a temporary directory will be created for storing the frames.

    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`(filename=None, show_path=False, use_ffmpeg=False)

    Save this animation.

    INPUT:

    - `filename` - (default: None) name of save file
    - `show_path` - boolean (default: False); if True, print the path to the saved file
    - `use_ffmpeg` - boolean (default: False); if True, use ‘ffmpeg’ by default instead of ‘convert’ when creating GIF files.

    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`(delay=20, iterations=0)

    Show this animation.

    INPUT:

    - `delay` - (default: 20) delay in hundredths of a second between frames
    - `iterations` - integer (default: 0); number of iterations of animation. If 0, loop forever.

    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.

`sage.plot.animate.``animate`(frames, **kwds)

  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

### Navigation

- index
- modules |
- next |
- previous |
- 2D Graphics »