matplotlib 在 pcolorfast 上内存溢出
问题:
我现在正在从文本文件中加载列数据到numpy数组里,然后绘制这些数据并保存生成的图像。因为这些值总是均匀分布在一个网格上,所以我觉得可以使用pcolorfast。每个数组都是正方形的,通常大小在1024x1024到8192x8192之间。目前,我只关心4096x4096及以下的大小。这项工作需要处理数百个文件,虽然第一个图像能够成功生成,但后续的图像却因为内存错误而崩溃。
未成功的解决方案:
我已经确保按照这里的建议,将rc中的hold设置为False。
限制:
图像必须使用所有的4096x4096的值,不能缩小到1024x1024(正如这里所建议的那样)。
备注:
在每个阶段(创建空数组、加载值、绘图、保存)观察内存使用情况后,我发现数组A在makeFrame完成后仍然占用内存。是否需要明确调用删除它?fig是否需要明确删除,还是pylab会处理这个问题?理想的情况(可能很明显)是内存使用量能回到调用makeFrame()之前的水平。
任何建议都非常感谢。我已经尝试解决这个问题几天了,所以很可能我错过了一些明显的东西。如果有简单的解决方案,那就太好了(如果这个问题更复杂的话,那就另当别论了)。
当前代码示例:
import numpy
import matplotlib
matplotlib.use("AGG")
import matplotlib.pylab as plt
def makeFrame(srcName, dstName, coloring, sideLength,
dataRanges, delim, dpi):
v,V,cmap = coloring
n = sideLength
xmin,xmax,ymin,ymax = dataRanges
A = numpy.empty((n,n),float)
dx = (xmax-xmin) / (n-1)
dy = (ymax-ymin) / (n-1)
srcfile = open(srcName,'rb')
for line in srcfile:
lineVals = line[:-1].split(delim)
x = float(lineVals[0])
y = float(lineVals[1])
c = float(lineVals[2])
#Find index from float value, adjust for rounding
i = (x-xmin) / dx
if (i - int(i) ) > .05: i += 1
j = (y-ymin) / dy
if (j - int(j) ) > .05: j += 1
A[i,j] = c
srcfile.close()
print "loaded vals"
fig = plt.figure(1)
fig.clf()
ax = fig.gca()
ScalarMap = ax.pcolorfast(A, vmin = v, vmax = V, cmap = cmap)
fig.colorbar(ScalarMap)
ax.axis('image')
fig.savefig(dstName, dpi = dpi)
plt.close(1)
print "saved image"
1 个回答
2
注意事项:
- 可能还有更好的方法来解决这个内存问题,我并不知道。
- 我还没能重现这个错误。当我使用
matplotlib.cbook.report_memory()
时,我的内存使用情况似乎正常。
尽管有这些注意事项,我还是想提到一个简单的方法来处理程序不释放内存的问题:使用 multiprocessing 模块,在一个单独的进程中运行出问题的函数。等这个函数结束后,再调用它。每次子进程结束时,你就会重新获得它使用的内存。
所以我建议试试这样的做法:
import matplotlib.cbook as mc
import multiprocessing as mp
import matplotlib.cm as cm
if __name__=='__main__':
for _ in range(10):
srcName='test.data'
dstName='test.png'
vmin = 0
vmax = 5
cmap = cm.jet
sideLength = 500
dataRanges = (0.0,1.0,0.0,1.0)
delim = ','
dpi = 72
proc=mp.Process(target=makeFrame,args=(
srcName,dstName,(vmin,vmax,cmap),sideLength,
dataRanges,delim,dpi))
proc.start()
proc.join()
usage=mc.report_memory()
print(usage)