Search code examples
pythonanimationmatplotlibimagemagicksgi

Saving a matplotlib animation with imagemagick, and without ffmpeg or mencoder


I want to create an animation of a calculated function. I'm not able to install ffmpeg or mencoder on the cluster I'm using to run the animation, but imagemagick is installed. matplotlib.animation apparently supports imagemagick as a writer for animations (see here, for example). The documentation says that the supported formats are:

['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp', 'pbm', 'raw', 'rgba']

I recognize several of these as non-animated file types, but apparently ffmpeg supports .sgi files in some way. It's fine if the codec that I have to use on the cluseter is obscure if I can convert it on my home computer with ffmpeg or mencoder.

How can I use imagemagick to save an animation with matplotlib?


Solution

  • This old post popped up while I was struggling to get some matplotlib animations exported as an animated gif. It's not rocket science, but still somewhat of a hassle to set up the first time around. I'll leave this post for future reference.

    As for the specifics when setting up this environment on a cluster, you'll have to translate each step for the specific needs for your server I guess. Animated gif is at least one of the animation options offered by the ImageMagickWriter, but there may be more.

    How-to

    • Get the ImageMagick binaries
    • Set an environment variable MAGICK_HOME pointing to the '<your-install-dir>\modules\coders' folder (see the docs. When on windows, remember to log off and back on)
    • point matplotlib to the install dir of ImageMagick: (mpl docs on rcParams)

      import matplotlib.pyplot as plt
      plt.rcParams['animation.convert_path'] = '<your-install-dir>/magick.exe'
      
    • Export your animation! (mpl docs on ImageMagickFileWriter)

      writer = ImageMagickFileWriter()
      your_animation.save('location.gif', writer=writer)
      

    Note that by default, errors thrown by ImageMagick will not reach you, apart from a nonzero return code. To get more extensive feedback, you'll need something like

    import matplotlib as mpl
    mpl.verbose.set_level("helpful")
    

    Bonus

    As a bonus, here's a proof-of-life:

    Mother's age at first pregnancy in The Netherlands