9

I've been trying to export an animated gif on my windows computer for several days.

Here is the basic code:

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

fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro', animated=True)

def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(frame):
    xdata.append(frame)
    ydata.append(np.sin(frame))
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                    init_func=init, blit=True)
ani.save("test.gif")
plt.show()

And the error:

>>> python .\anim_test.py
Traceback (most recent call last):
  File ".\anim_test.py", line 22, in <module>
    ani.save("test.gif")
  File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 1063, in save
    writer.grab_frame(**savefig_kwargs)
  File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 336, in grab_frame
    'with --verbose-debug.'.format(e, out, err))
IOError: Error saving animation to file (cause: [Errno 22] Invalid argument) Stdout:  StdError: . It may help to re-run
with --verbose-debug.
PS C:\Users\ishma\Dropbox (SteinLab)\spectra\MassSpecPlot> python .\anim_test.py --verbose-debug
$HOME=C:\Users\ishma
matplotlib data path C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\mpl-data

*****************************************************************
You have the following UNSUPPORTED LaTeX preamble customizations:

Please do not ask for support with these customizations active.
*****************************************************************

loaded rc file C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\mpl-data\matplotlibrc
matplotlib version 2.0.2
verbose.level debug
interactive is False
platform is win32
loaded modules: <dictionary-keyiterator object at 0x0000000003EA0048>
CACHEDIR=C:\Users\ishma\.matplotlib
Using fontManager instance from C:\Users\ishma\.matplotlib\fontList.cache
backend Qt5Agg version 5.6
Animation.save using <class 'matplotlib.animation.FFMpegWriter'>
frame size in pixels is 640 x 480
MovieWriter.run: running command: ffmpeg -f rawvideo -vcodec rawvideo -s 640x480 -pix_fmt rgba -r 5.0 -i pipe: -vcodec h
264 -pix_fmt yuv420p -y test.gif
MovieWriter.grab_frame: Grabbing frame.
findfont: Matching :family=sans-serif:style=normal:variant=normal:weight=400:stretch=normal:size=10.0 to DejaVu Sans (u'
C:\\Users\\ishma\\Anaconda2\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSans.ttf') with score of 0.0000
00
MovieWriter.grab_frame: Grabbing frame.
MovieWriter -- Error running proc:
None
None
MovieWriter -- Command stdout:
None
MovieWriter -- Command stderr:
None
Traceback (most recent call last):
  File ".\anim_test.py", line 22, in <module>
    ani.save("test.gif")
  File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 1063, in save
    writer.grab_frame(**savefig_kwargs)
  File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 336, in grab_frame
    'with --verbose-debug.'.format(e, out, err))
IOError: Error saving animation to file (cause: [Errno 22] Invalid argument) Stdout: None StdError: None. It may help to
 re-run with --verbose-debug.

If I switch the output file type to mp4, the code works. After reading many threads from people with errors producing video files, I feel like I have tried every combination of different writers (including FFMpegWriter, ImageMagickWriter, AVConvWriter, and the FileWriters as well), made sure the relevant programs are in my PATH, changed settings in matplotlibrc, and tried multiple computers. I'm stumped.

I've found only one thread referencing this exact error: https://stackoverflow.com/questions/46562938/oserror-errno-22-invalid-argument-error-saving-animation-to-file

But following the advice in the comments there haven't solved my problem.

Any ideas? Thanks for any help.

ishmandoo
  • 413
  • 5
  • 10

1 Answers1

7

With the code from the question you are basically asking to produce an animated gif using the MPEG writer. The MPEG writer however is only able to produce videos.

The standard way to produce an animated gif through the matplotlib animation module is to use ImageMagick.

So first change your line to

ani.save("test.gif",writer="imagemagick")

Now for this to work the rcParam animation.convert_path must point to the ImageMagick's convert program.
It seems you are on windows here, so it's best to include the complete path to it. Hence, before the saving, set

plt.rcParams["animation.convert_path"] = "C:\ProgramFiles\ImageMagick\convert.exe" 

or whatever your path to the convert.exe may be.

Now it may apparently happen that convert.exe is not part of newer versions of imageMagick anymore. The documentation says

If these tools are not available, you can simply append them to the magick tool like this:
magick convert.

For the matplotlib animation this means that you would need to set an extra argument. Set the path to

plt.rcParams["animation.convert_path"] = "C:\ProgramFiles\ImageMagick\magick.exe"

then call

ani.save("test.gif",writer="imagemagick", extra_args="convert")
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • My install of ImageMagick doesn't seem to have a convert.exe in it. Should it? I see an ffmpeg.exe in my ImageMagick directory, though. – ishmandoo Oct 12 '17 at 21:58
  • If you are using ImageMagick 7, then convert has been renamed to magick. So do you have magick.exe? – fmw42 Oct 12 '17 at 21:59
  • @fmw42 I do have `ImageMagick-7.0.3-Q16` and I do have a `convert.exe`. I also have a `magick.exe`, but that is not useful in this case. Do you have any source for your claim about renaming? Otherwise I wouldn't trust that. – ImportanceOfBeingErnest Oct 12 '17 at 22:03
  • But you are in thus far correct, as apparently, there are version which do not have all the command tools. [The documentation](https://www.imagemagick.org/script/command-line-tools.php) says: "If these tools are not available, you can simply append them to the magick tool like this: `magick convert`". I will update the answer. – ImportanceOfBeingErnest Oct 12 '17 at 22:21
  • 1
    magick is the new IM 7 version of convert. In IM 7 if you have convert, then it is the legacy IM 6 version that is an option with Windows install when you click the legacy checkbox. Using magick convert is not the same as magick, but may (?) be the same as the legacy convert. I am not sure on that point. So if you have convert and want to use the legacy code, then it should still work with convert.exe. Perhaps the tool you are using does not properly recognize IM 7 and you may want to fall back an remove it and install the older IM 6 – fmw42 Oct 13 '17 at 00:35
  • I'm not sure what you are saying, but in any case, as I said, I have updated the solution to work with magick.exe. – ImportanceOfBeingErnest Oct 13 '17 at 00:36