From: Tony Yu <ts...@gm...> - 2012-07-03 03:43:14
|
On Sun, Jun 24, 2012 at 10:02 AM, Tony Yu <ts...@gm...> wrote: > I'm having a tough time figuring this out: Saving an animation seems to > hang when using `streamplot`. The exact same animation runs without issue > when calling show. > > On my system, the example below hangs consistently at frame 173. However, > the number of saved frames (before hanging) varies with density of stream > lines (i.e. number of line segments in streamplot): More frames saved for > lower density. > > Seems to be a memory or file-size issue, but > > * Memory use doesn't seem to grow. (this suggests that ffmpeg adds > frames to disk as opposed to memory.) > * Saving the animation up to the frame just before it hangs gives > modest (~1MB) videos. > Maybe this is a limitation of `ffmpeg`? > > Can someone confirm that the example hangs on their system? (Somehow, I > often run into bugs that are not reproducible.) > > In case this is system dependent: > * OSX 10.6 > * Python 2.6.1 (system install) > * matplotlib master > * ffmpeg 0.10 > > Simple plots seem to work fine, but I should probably try to reproduce > using something other than streamplot (maybe create the equivalent number > of line and arrow collections). > > -Tony > > #~~~ Example > import numpy as np > import matplotlib.pyplot as plt > import matplotlib.animation as animation > > fig, ax = plt.subplots() > > # do nothing function that prints frame > def update(frame_num): > print frame_num > return [] > > Y, X = np.mgrid[:1:100j, :1:100j] > U = np.ones_like(X) > V = np.ones_like(X) > ax.streamplot(X, Y, U, V, density=1) > > ani = animation.FuncAnimation(fig, update, save_count=500) > > # save hangs at frame 173 (this probably varies by system, if it's > reproducible). > ani.save('animation.avi') > # show animates all frames w/o issue. > #plt.show() > > > I finally had some time to revisit this issue. It seems that subprocess PIPEs have fairly limited buffers [1] (also see docs for `subprocess.Popen.communicate` [2]) and ffmpeg tends to generate a decent amount of output to stderr. A simple solution is to redirect stderr to a temporary file. This change fixes the issue on my system. If this bug is reproducible, I can submit a PR. The temporary file here could be created using tempfile so it gets cleaned up automatically, or maybe a more permanent log file for debugging. Thoughts? -Tony [1] http://thraxil.org/users/anders/posts/2008/03/13/Subprocess-Hanging-PIPE-is-your-enemy/ [2] http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate |