使用matplotlib进行性能考虑的动画中的内存泄漏



最近,我正在使用Matplotlib使用Python进行动画。一开始,我跟随在网中搜索的示例,该示例具有以下结构:

=========================================================================
import matplotlib.pyplot as plot
import matplotlib.animation as anim
def animate(i):
    ax.clear()
    # Re-plot the figure with updated animation data
if __name__ == "__main__":
    fig, ax = plot.subplots(fsigsize=(8,4))
    an = anim.FuncAnimation(fig, animate, interval=1)
    plot.show()
=========================================================================

此代码似乎还可以。没有内存泄漏。但是问题在于它运行太慢。因为在使用更新的动画数据重新生成图时,必须一次又一次地完成绘图的所有设置(例如Set_xlim(),set_ylim(),绘制轴等)。因此,我试图以这种方式提高性能:

========================================================================
import matplotlib.pyplot as plot
import matplotlib.animation as anim
def init():
    ax.set_title("....")
    ax.set_xlim(-1, 1)
    ax.set_ylim(-10,10)
    # plot axes, and all the patterns which are fixed in the animation
def animate(i):
    # x[] and y[] are large arrays with updated animation data
    if ('la' in globals()): la.remove()
    la, = ax.plot(x, y)
if __name__ == "__main__":
    fig, ax = plot.subplots(figsize=(8,4))
    an = anim.FuncAnimation(fig, animate, init_func=init, interval=1)
    plot.show()
========================================================================

以这种方式,仅重新设计了主要曲线" LA"。其他固定零件仅在init()子例程中完成一次。现在,动画运行得更快。但是出现了严重的内存泄漏。在动画过程中运行"顶部",我看到被占领的内存不断成长。测试后,我确定此语句是内存泄漏的来源:

la, = ax.plot(x, y)

一些讨论表明,内存泄漏是由于图" AX"未关闭。但是,如果我每次都关闭图以更新图形,则性能事实太慢了。

有更好的解决这个问题的方法吗?

我的环境:Python 3.4,Matplotlib-1.4.2,Debian GNU/Linux 8.8。我还在python 3.6,matplotlib-2.1.0中测试了Cygwin和MacosX。情况相同。

非常感谢您的帮助。

t.h.hsieh

对不起,我只是找出答案。更新动画中的绘图的正确方法应"设置新数据",而不是"删除和重新绘制曲线"或"再生图"。因此,我的代码应更改为:

=====================================================================
import matplotlib.pyplot as plot
import matplotlib.animation as anim
def init():
    global ax, la
    ax.set_title("....")
    ax.set_xlim(-1, 1)
    ax.set_ylim(-10,10)
    # get the initial data x[], y[] to plot the initial curve
    la, = ax.plot(x, y, color="red", lw=1)
def animate(i):
    global fig, la
    # update the data x[], y[], set the updated data, and redraw.
    la.set_xdata(x)
    la.set_ydata(y)
    fig.canvas.draw()
if __name__ == "__main__":
    fig, ax = plot.subplots(fsigsize=(8,4))
    an = anim.FuncAnimation(fig, animate, interval=1)
    plot.show()
=====================================================================    

无论如何,要感谢那些发表评论的人,这表明我找到答案。

最好的问候

t.h.hsieh

最新更新