Python matplotlib:指定图形大小时未释放内存

时间:2010-09-02 03:08:59

标签: python memory-management matplotlib

我正在使用matplotlib生成许多数值模拟结果图。这些图用作视频中的帧,因此我通过重复调用类似于此的函数来生成许多图:

from pylab import *

def plot_density(filename,i,t,psi_Na):  
    figure(figsize=(8,6))
    imshow(abs(psi_Na)**2,origin = 'lower')
    savefig(filename + '_%04d.png'%i)
    clf()

问题是每次调用此函数时,python进程的内存使用量会增加几兆字节。例如,如果我用这个循环调用它:

if __name__ == "__main__":
    x = linspace(-6e-6,6e-6,128,endpoint=False)
    y = linspace(-6e-6,6e-6,128,endpoint=False)
    X,Y = meshgrid(x,y)
    k = 1000000
    omega = 200
    times = linspace(0,100e-3,100,endpoint=False)
    for i,t in enumerate(times):
        psi_Na = sin(k*X-omega*t)
        plot_density('wavefunction',i,t,psi_Na)
        print i

然后ram的使用量随着时间的推移而增长到600MB。但是,如果我在函数定义中注释掉行figure(figsize=(8,6)),那么ram的使用率将保持稳定在52MB。 (8,6)是默认的数字大小,因此在两种情况下都会生成相同的图像。我想从我的数值数据中制作不同大小的图,而不会耗尽ram。我怎么能强迫python释放这个记忆?

我已经尝试gc.collect()每个循环强制垃圾收集,我已经尝试f = gcf()获取当前数字,然后del f删除它,但无济于事。

我在64位Ubuntu 10.04上运行CPython 2.6.5。

2 个答案:

答案 0 :(得分:35)

来自pylab.figure的文档字符串:

In [313]: pylab.figure?
  

如果要创建许多数字,请制作   确定你明确地打电话给“关闭”   你没有使用的数字,因为   这将使pylab正常运行   清理记忆。

所以也许试试:

pylab.close()     # closes the current figure

答案 1 :(得分:9)

关闭一个数字绝对是一个选择,然而,重复多次,这是耗时的。我建议有一个持久的图形对象(通过static function variable,或作为附加函数参数)。如果该对象为fig,则该函数将在每个绘图周期之前调用fig.clf()

from matplotlib import pylab as pl
import numpy as np

TIMES = 10
x = np.linspace(-10, 10, 100)
y = np.sin(x)
def withClose():
    def plotStuff(i):
        fig = pl.figure()
        pl.plot(x, y + x * i, '-k')
        pl.savefig('withClose_%03d.png'%i)
        pl.close(fig)
    for i in range(TIMES):
        plotStuff(i)


def withCLF():
    def plotStuff(i):
        if plotStuff.fig is None:
            plotStuff.fig = pl.figure()
        pl.clf()
        pl.plot(x, y + x * i, '-')
        pl.savefig('withCLF_%03d.png'%i)
    plotStuff.fig = None

    for i in range(TIMES):
        plotStuff(i)

这是时间值

In [7]: %timeit withClose()
1 loops, best of 3: 3.05 s per loop

In [8]: %timeit withCLF()
1 loops, best of 3: 2.24 s per loop