EDIT: SOLVED
But i'm not sure how... i moved as much as I could to pylab instead of pyplot, implemented a multiprocessing approach described [here][1], and at that point it was working fine. Then in an attempt to pinpoint the issue, i reversed my code step-by-step. But it kept working, even without the multiprocessing, even with pyplot, etc. Only when i take off fig.clf() now it does not work, which is what most people seem to experience but was not the issue with me initially. Well maybe it was, maybe the clf() statement wasnt at the right place or something. Thanks !
EDIT: ISSUE STILL NOT SOLVED
That's very surprising. I now moved my savefig() function into an external module, which I import when executing my script. Here is the function:
def savethefig(fig,outpath,luname):
plt.savefig(outpath+luname+'testredtarget.png',dpi=500)
So now i do something like:
from myfile import savethefig
fig = plt.figure()
ax1 = fig.add_subplot(311)
pftmap=zeros(shape=(1800,3600))*nan
for i in range(len(pftspatialnames)):
pftmap[indlat,indlon]=data[i,:]
fig = pylab.gcf()
a1=ax1.imshow(pftmap, interpolation='nearest',origin='upper', aspect='auto')
savethefig(fig,outpath,luname)
I did everything step by step, line by line and the RAM definitely goes up when hiting the savefig() function within the external function. Goes up by about 500MB. Then when going back to the main script, that memory is not released. Aren't external function supposed to clear everything ? I'm missing something...
ORIGINAL POST:
I'm using python EDP 7.3-2 (32 bit) (python 2.7.3).
I have a program that does some computations, then maps some of the results out and saves the images, with matplotlib.
That's a pretty large amount of data, and if i try to map and save too many images, I hit a memory limit. Which I shouldnt since I re-use the same figure, and dont create new variables. I've struggled for a while with that, tried all the figure clearing/deleting etc solutions, changing the backend used by matplotlib, but nothing does it, everytime the code hits the savefig function, it adds a lot of memory and does not take it off later.
I'm far from being an expert on memory stuff (or python by the way), but here is one diagnose attempt i ran, using the module objgraph:
from numpy import *
import matplotlib
matplotlib.use('Agg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib import pyplot as plt
outpath = '/Users/yannick/Documents/outputs/'
pftspatialnames = ['forest','shrubs','grass']
Computations (not shown)
fig = plt.figure()
for i in range(len(pftspatialnames)):
pftmap=zeros(shape=(1800,3600))*nan
pftmap[indlat,indlon]=data[i,:]
fig = pylab.gcf()
ax1 = plt.subplot2grid((3,1),(0,0))
a1=ax1.imshow(pftmap, interpolation='nearest',origin='upper', aspect='auto')
del(pftmap)
gc.collect()
print 'MEMORY LEAK DETECTOR before figsave'
objgraph.show_growth()
plt.savefig(outpath+pftspatialnames[i]+'testredtarget.png', dpi=500)
print 'MEMORY LEAK DETECTOR after figsave'
objgraph.show_growth()
Pretty big maps (and there's 3 of them, 3 subplots, just showed one here), but it handles it pretty well. It takes about 4 figures to saturate memory. Some stuff may be superfluous (e.g. deleting pftmap), but i was trying everything to clear some memory.
And here is the printed output:
MEMORY LEAK DETECTOR before figsave
dict 6640 +2931
weakref 3218 +1678
instance 1440 +1118
tuple 3501 +939
function 12486 +915
Bbox 229 +229
instancemethod 684 +171
Line2D 147 +147
TransformedBbox 115 +115
Path 127 +114
MEMORY LEAK DETECTOR after figsave
dict 7188 +548
Path 422 +295
weakref 3494 +276
instance 1679 +239
tuple 3703 +202
function 12670 +184
TransformedPath 87 +87
instancemethod 741 +57
Line2D 201 +54
FontProperties 147 +36
So before calling savefig there's a lot of new objects (that's normal i do a bunch of stuff in the code before). But then by just calling savefig we add 550 dict, etc. Could that be the source of my problem ? Note that this happens the first time i call savefig only. Any subsequent call does the following:
MEMORY LEAK DETECTOR before figsave
MEMORY LEAK DETECTOR after figsave
tuple 3721 +6
dict 7206 +6
function 12679 +3
list 2001 +3
weakref 3503 +3
instance 1688 +3
Bbox 260 +3
but memory still keeps growing and soon i hit memory limit.
Thanks a lot !