From: Ryan M. <rm...@gm...> - 2012-07-03 14:22:40
|
On Tue, Jul 3, 2012 at 9:14 AM, Tony Yu <ts...@gm...> wrote: > On Mon, Jul 2, 2012 at 11:42 PM, Tony Yu <ts...@gm...> wrote: >> 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 >> > > And just to clarify: My original email mentioned that saving would hang only > when `streamplot` was used to create the figure. It turns out that ffmpeg > prints more output (keyframes?) for more complex images, so when I ran > simpler plots, they didn't produce enough output to fill the subprocess > `PIPE` (although they would eventually). > > Also, theres's a simpler fix than piping ffmpeg output to a file: Just set > `-loglevel quiet` in the ffmpeg command. > > -Tony It's not a bad idea to have it logged to a file in a temp directory. We could potentially just do this if debug is set to verbose, however, and just use -loglevel quiet otherwise. Can you manage PR for this or do I need to? Ryan -- Ryan May Graduate Research Assistant School of Meteorology University of Oklahoma |