Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

python - Exporting animated gif using matplotlib

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:UsersishmaAnaconda2libsite-packagesmatplotlibanimation.py", line 1063, in save
    writer.grab_frame(**savefig_kwargs)
  File "C:UsersishmaAnaconda2libsite-packagesmatplotlibanimation.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:UsersishmaDropbox (SteinLab)spectraMassSpecPlot> python .anim_test.py --verbose-debug
$HOME=C:Usersishma
matplotlib data path C:UsersishmaAnaconda2libsite-packagesmatplotlibmpl-data

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

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

loaded rc file C:UsersishmaAnaconda2libsite-packagesmatplotlibmpl-datamatplotlibrc
matplotlib version 2.0.2
verbose.level debug
interactive is False
platform is win32
loaded modules: <dictionary-keyiterator object at 0x0000000003EA0048>
CACHEDIR=C:Usersishma.matplotlib
Using fontManager instance from C:Usersishma.matplotlibfontList.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:UsersishmaAnaconda2libsite-packagesmatplotlibanimation.py", line 1063, in save
    writer.grab_frame(**savefig_kwargs)
  File "C:UsersishmaAnaconda2libsite-packagesmatplotlibanimation.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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:ProgramFilesImageMagickconvert.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:ProgramFilesImageMagickmagick.exe"

then call

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...