Python matplotlib: memory not being released when specifying figure size

邮差的信 提交于 2019-12-31 11:41:22

问题


I'm using matplotlib to generate many plots of the results of a numerical simulation. The plots are used as frames in a video, and so I'm generating many of them by repeatedly calling a function similar to this one:

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()

The problem is that the memory usage of the python process grows by a couple of megabytes with every call to this function. For example if I call it with this loop:

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

then the ram usage grows with time to 600MB. If however I comment out the line figure(figsize=(8,6)) in the function definition, then the ram usage stays steady at 52MB. (8,6) is the default figure size and so identical images are produced in both cases. I'd like to make different sized plots from my numerical data without running out of ram. How might I force python to free up this memory?

I've tried gc.collect() each loop to force garbage collection, and I've tried f = gcf() to get the current figure and then del f to delete it, but to no avail.

I'm running CPython 2.6.5 on 64 bit Ubuntu 10.04.


回答1:


From the docstring for pylab.figure:

In [313]: pylab.figure?

If you are creating many figures, make sure you explicitly call "close" on the figures you are not using, because this will enable pylab to properly clean up the memory.

So perhaps try:

pylab.close()     # closes the current figure



回答2:


Closing a figure is definitely an option, however, repeated many times, this is time consuming. What I suggest is to have a single persistent figure object (via static function variable, or as additional function argument). If that object is fig, the function will then call fig.clf() before each plotting cycle.

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)

Here is the timing values

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


来源:https://stackoverflow.com/questions/3623600/python-matplotlib-memory-not-being-released-when-specifying-figure-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!