Python matplotlib: la memoria no se libera al especificar el tamaño de la figura

Estoy usando matplotlib para generar muchas gráficas de los resultados de una simulación numérica. Las gráficas se usan como cuadros en un video, por lo que estoy generando muchas de ellas llamando repetidamente a una función similar a esta:

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

El problema es que el uso de memoria del proceso de Python aumenta en un par de megabytes con cada llamada a esta función. Por ejemplo si lo llamo con este bucle:

 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 

entonces el uso del ariete crece con el tiempo a 600MB. Sin embargo, si comento la figure(figsize=(8,6)) de la línea figure(figsize=(8,6)) en la definición de la función, entonces el uso del ariete permanece constante en 52MB. (8,6) es el tamaño de figura predeterminado y, por lo tanto, se producen imágenes idénticas en ambos casos. Me gustaría hacer diagtwigs de diferentes tamaños a partir de mis datos numéricos sin quedarse sin RAM. ¿Cómo podría forzar a Python a liberar esta memoria?

He intentado gc.collect() cada bucle para forzar la recolección de basura, y he intentado f = gcf() para obtener la cifra actual y luego del f para eliminarla, pero sin éxito.

Estoy ejecutando CPython 2.6.5 en Ubuntu 10.04 de 64 bits.

De la cadena de pylab.figure para pylab.figure :

 In [313]: pylab.figure? 

Si está creando muchas figuras, asegúrese de llamar explícitamente “cerrar” a las figuras que no está usando, ya que esto permitirá que Pylab limpie la memoria correctamente.

Así que tal vez intente:

 pylab.close() # closes the current figure 

Cerrar una figura es definitivamente una opción, sin embargo, repetida muchas veces, esto requiere mucho tiempo. Lo que sugiero es tener un solo objeto de figura persistente (a través de la variable de función estática , o como un argumento de función adicional). Si ese objeto es fig , la función llamará a fig.clf() antes de cada ciclo de trazado.

 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) 

Aquí están los valores de tiempo

 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