matplotlib animation.save到动画gif很慢

时间:2015-06-06 23:26:16

标签: python matplotlib imagemagick animated-gif

我正在制作一个我在IPython 3.1笔记本中模拟的融合过程。我在matplotlib动画中可视化散点图结果,我正在通过ImageMagick写出动画gif。有3000帧,每帧约5000点。

我不确定matplotlib是如何创建这些动画文件的,但它似乎缓存了一堆帧然后将它们全部写在一起 - 当我看到CPU使用情况时,它在开始时由python占主导地位然后通过最后的转换。

写出gif的速度非常慢。在现代MacBook Pro上写一个70MB的文件到SSD需要一个多小时。 'convert'相当于4(8个超线程)核心机器上一个核心的90%。

写入前65MB需要大约15分钟,写入最后5MB需要2个多小时。

我认为代码的有趣内容如下:如果还有其他有用的东西,请告诉我。

def updateAnim(i,cg,scat,mags):
    if mags[i]==0: return scat,
    cg.convergeStep(mags[i])
    scat.set_offsets(cg._chrgs[::2,0:2])
    return scat,

fig=plt.figure(figsize=(6,10))
plt.axis('equal')
plt.xlim(-1.2,1.2);plt.ylim(-1,3)
c=np.where(co._chrgs[::2,3]>0,'blue','red')
scat=plt.scatter(co._chrgs[::2,0],co._chrgs[::2,1],s=4,color=c,marker='o',alpha=0.25);
ani=animation.FuncAnimation(fig,updateAnim,frames=mags.size,fargs=(co,scat,mags),blit=True);
ani.save('Files/Capacitance/SpherePlateAnimation.gif',writer='imagemagick',fps=30);

知道瓶颈可能是什么或者我如何加速它?与模拟时间相比,我更喜欢写出时间很短。

版本:ImageMagick 6.9.0-0 Q16 x86_64 2015-05-30 http://www.imagemagick.org 版权:版权所有(C)1999-2014 ImageMagick Studio LLC 特点:DPC模块 代表(内置):bzlib cairo djvu fftw fontconfig freetype gslib gvc jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png ps rsvg tiff webp wmf x xml zlib

ps -aef报道: convert -size 432x720 -depth 8 -delay 3.3333333333333335 -loop 0 rgba: - Files / Capacitance / SpherePlateAnimation.gif

1 个答案:

答案 0 :(得分:4)

<强>更新

在执行本次更新中建议的任何内容之前,请阅读以下原始答案。

如果您想在某种程度上调试它,可以将ImageMagick部分分开,并确定问题所在。要做到这一点,我会找到你的ImageMagick convert程序,如下所示:

which convert    # result may be "/usr/local/bin/convert"

然后转到包含目录,例如

cd /usr/local/bin

现在将原始convert程序保存为convert.real - 您可以随后通过撤消以下最后两个参数再次将其更改回来:

mv convert convert.real

现在,将以下文件另存为convert

#!/bin/bash
dd bs=128k > $HOME/plot.rgba 2> /dev/null

并通过执行

来制作可执行文件
chmod +x convert

现在,当您再次运行matplotlib时,它将执行上面的脚本而不是ImageMagick,脚本会将原始RGBA数据保存在名为{{1}的文件中的登录目录中}。这将告诉你两件事......首先你会看到plot.rgba现在运行得更快,因为不再有任何ImageMagick处理,其次你会看到文件大小是否像我猜的那样大约是4GB。

现在,您可以使用ImageMagick在 matplotlib完成后使用此处理文件,内存限制为10GB:

matplotlib

您还可以考虑将文件拆分为2(或4),使用convert.real -limit memory 10000000 -size 432x720 -depth 8 -delay 3.33 -loop 0 $HOME/plot.rgba Files/Capacitance/SpherePlateAnimation.gif 并将两个并行处理并将它们一起添加以查看是否有帮助。问一下,如果你想调查那个选项。

原始答案

我有点大声说话,希望它可以直接帮助你,或者让别人的大脑慢慢抓住问题...

您可以从命令行分享dd直接写入ImageMagick的matplotlib工具的stdin - 我可以从{{1}看到}参数告诉我它在convert上将RGB加上Alpha透明度作为原始值发送。

这意味着我没有建议将中间文件放在RAM磁盘上,这就是我在评论中所使用的位置......

第二件事是,当原始像素数据被发送时,每个像素都由RGBA:-计算并发送,因此它与模拟中的5,000个点不变 - 所以没有减少或优化的点点数。

另外需要注意的是,您使用的是ImageMagick的16位量化版本(版本字符串中为Q16)。这有效地使内存需求加倍,因此如果您可以轻松地重新编译ImageMagick以获得8位量子深度,那么这可能有所帮助。

现在,让我们看一下输入流,stdin表示每像素4个字节,每帧432x720像素,或每帧1.2MB。现在,你有3,000帧,所以最小3.6GB,加上75MB的输出文件。我怀疑这只是超出了ImageMagick的自然内存限制的限制,这就是为什么它在结束时放慢速度,所以我的建议是检查ImageMagick的内存限制并考虑将它们增加到4GB-6GB或更多,如果你有它。

检查内存和其他资源限制:

matplotlib

由于您无法提高RGBA -depth 8执行的命令行的内存限制,您可以通过在开始identify -list resource Resource limits: Width: 214.7MP Height: 214.7MP Area: 4.295GP Memory: 2GiB <--- Map: 4GiB Disk: unlimited File: 192 Thread: 1 Throttle: 0 Time: unlimited 之前导出的环境变量来执行此操作:

matplotlib

您也可以在matplotlib文件中更改它,但这更复杂,所以请先尝试这种方式并询问您是否卡住了!

请传递对此的反馈,因为我可能会建议其他事情,具体取决于是否有效。还请运行export MAGICK_MEMORY_LIMIT=4294967296 identify -list resource Resource limits: Width: 214.7MP Height: 214.7MP Area: 4.295GP Memory: 4GiB <--- Map: 4GiB Disk: unlimited File: 192 Thread: 1 Throttle: 0 Time: unlimited 并编辑您的问题并将输出粘贴到那里。