que - python graficos 2d
Matplotlib de Python: la memoria no se libera cuando se especifica el tamaƱo de la figura (2)
De docstring para pylab.figure
:
In [313]: pylab.figure?
Si está creando muchas figuras, asegúrese de llamar explícitamente "cerrar" las cifras que no está utilizando, ya que esto permitirá a pylab limpiar adecuadamente la memoria.
Entonces tal vez intente:
pylab.close() # closes the current figure
Estoy usando matplotlib para generar muchas representaciones de los resultados de una simulación numérica. Las tramas se utilizan como marcos 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 crece 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 ram aumenta 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 ram se mantiene estable 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 trazados de diferentes tamaños a partir de mis datos numéricos sin quedarme sin RAM. ¿Cómo podría forzar a Python a liberar este recuerdo?
He intentado con gc.collect()
cada ciclo para forzar la recolección de elementos no utilizados, y he intentado con f = gcf()
obtener la figura actual y luego con del f
para eliminarla, pero fue en vano.
Estoy ejecutando CPython 2.6.5 en Ubuntu 10.04 de 64 bits.
El cierre de una figura es definitivamente una opción, sin embargo, repetida muchas veces, esto lleva mucho tiempo. Lo que sugiero es tener un único objeto figura persistente (a través de la variable de función estática o como 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