我正在使用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。
答案 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