如何使用Matplotlib创建高分辨率动画而没有内存问题?

时间:2018-08-08 23:07:54

标签: python-3.x animation matplotlib

我想创建一个Matplotlib热图动画,该动画至少具有200 * 300的分辨率和500帧。问题是我拍摄的动画的标准方法存在大量内存泄漏(如this question *中所述)。当动画开始绘制或写出时,RAM开始被填满,直到系统冻结直到脚本被杀死为止。太糟糕了,甚至连我的4GB RAM和4GB交换都不够。除了创建较小的块并一起编辑之外,还有什么方法可以制作该动画?

这是我的代码,有一点简化。 (注意:这可能需要几分钟才能运行,并且可能会完全填满您的内存,从而导致死机。)

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

def waveanim(frames, trange, xbounds, ybounds, xnum, ynum, fps):

    xpoints = np.linspace(*xbounds, xnum)
    ypoints = np.linspace(*ybounds, ynum)
    tmin, tmax = trange

    # this part is a complicated calculation in my actual code; point is I have all the 
    # values for all the time points in an array that I calculate like this ready before 
    # I even start animating. (Since the calculation involves an inverse FFT, I can't just use NumPy's cool array managing abilities as ImportanceOfBeingErnest's answer suggests.)
    result = np.empty((xnum, ynum, frames), dtype="float64")
    for i, x in enumerate(xpoints):
        print("calculating: {} out of {}".format(i, len(xpoints)), end='\r')
        for j, y in enumerate(ypoints):
            arr = np.array([np.sin(x+t) + np.cos(x-y-2*t) for t in np.linspace(tmin, tmax, frames)])
            result[i,j] = arr
    print('\n')
    def animate(i):
        print("animating: {} out of {}".format(i, frames), end='\r')
        val = result[:,:,i].transpose()
        pc = plt.pcolor(xpoints, ypoints, val, cmap='jet')
        return pc,

    fig, ax = plt.subplots()
    im_ani = animation.FuncAnimation(fig, animate, frames=frames, interval=1000/fps, repeat_delay=0, blit=True)
    plt.show()


def main():

    trange = (-10.0, 10.0)
    xbounds = (-20.0, 20.0)
    ybounds = (-20.0, 20.0)
    frames = 100
    xnum = 300
    ynum = 300
    fps = 25
    waveanim(frames, trange, xbounds, ybounds, xnum, ynum, fps)

if __name__ == '__main__':
     main()

我还尝试了分别生成图,将它们放在一个数组中,然后将该数组放入ArtistAnimation中,就像在this example中一样,但是结果是相同的。

*我不是骗人的,因为a)我在Kubuntu上工作,而不是在iOS上工作,并且该修复程序是特定于OS的,并且b)因为我不限制解决泄漏漏洞的解决方案。

1 个答案:

答案 0 :(得分:1)

您将在同一图中创建100个ERROR TypeError: "_co.box is undefined" View_CategoriesComponent_5ng:///AppModule /CategoriesComponent.ngfactory.js:28:11 handleEventhttp://localhost:4200/vendor.js:41342:16 callWithDebugContexthttp://localhost:4200/vendor.js:42435:22 debugHandleEventhttp://localhost:4200/vendor.js:42138:12 dispatchEventhttp://localhost:4200/vendor.js:38801:16 renderEventHandlerClosurehttp://localhost:4200/vendor.js:39245:38 decoratePreventDefaulthttp://localhost:4200/vendor.js:51364:36 invokeTaskhttp://localhost:4200/polyfills.js:2743:17 onInvokeTaskhttp://localhost:4200/vendor.js:34899:24 invokeTaskhttp://localhost:4200/polyfills.js:2742:17 runTaskhttp://localhost:4200/polyfills.js:2510:28 invokeTaskhttp://localhost:4200/polyfills.js:2818:24 invokeTaskhttp://localhost:4200/polyfills.js:3862:9 globalZoneAwareCallbackhttp://localhost:4200/polyfills.js:3888:17 CategoriesComponent.html:35:10 图。可以肯定的是。为了有效地使用内存,您将只使用一个plt.pcolor图。然后,您可以在每个动画步骤中更新此图。 (实际上,链接的问题中也使用了这个概念,只是用于不同的绘图类型。)

为节省计算时间,您也可以摆脱嵌套的python循环来填充数组,而是使用numpy在网格上评估函数。这样可以将时间减少到动画开始的时间,从大约1分钟缩短到几秒钟。

plt.pcolor
相关问题