pyplot close clean cla all python memory backend matplotlib

python - close - pyplot erase



Matplotlib y Pyplot.close() no liberan memoria?-Qt4Agg relacionado con el backend (2)

Creo que la razón por la que está haciendo esto es porque a medida que pasa por todos los diferentes gráficos, se queda sin memoria, probablemente porque no lo está liberando correctamente.

¿Por qué no intentas crear aproximadamente 3 o más programas, cada uno de los cuales hace unos pocos gráficos en lugar de un solo programa haciendo todos los gráficos?

Programa 1: Gráficos 1-8

Programa 2: Gráficos 9-16

Programa 3: Gráficos 17-25

Espero que esto ayude @FakeDIY:)

EDITAR: Si explicity cambiar el backend para matplotlib de ''Qt4Agg'' a simplemente ''Agg'', entonces puedo ejecutar mi código sin errores. Supongo que esto es un error en el back-end?

Estoy escribiendo un código para procesar una cantidad bastante grande de datos automáticamente. El código primero analiza mis archivos de datos y almacena todos los bits relevantes. Luego tengo diferentes funciones para producir cada uno de los gráficos que necesito (hay alrededor de 25 en total). Sin embargo, sigo encontrando algún tipo de error de memoria y creo que es porque Matplotlib / PyPlot no están liberando la memoria correctamente.

Cada función de trazado finaliza con un comando pyplot.close (fig) y como solo quiero guardar los gráficos y no mirarlos de inmediato, no incluyen un pyplot.show ().

Si ejecuto las funciones de trazado individualmente en un intérprete, entonces no tengo ningún problema. Sin embargo, si hago una función separada que llama a cada función de trazado alternadamente entonces me encuentro con un "MemoryError: Could not allocate memory for path".

¿Alguien ha encontrado un problema como este? Parece estar relacionado con Matplotlib se queda sin memoria cuando se traza en un bucle pero pyplot.close () no soluciona mi problema.

Así es como se ve una función de parcela típica en mi código:

def TypicalPlot(self, title=None, comment=False, save=False, show=True): if title is None: title = self.dat.title fig = plt.figure() host = SubplotHost(fig, 111) fig.add_subplot(host) par = host.twinx() host.set_xlabel("Time (hrs)") host.set_ylabel("Power (W)") par.set_ylabel("Temperature (C)") p1, = host.plot(self.dat.timebase1, self.dat.pwr, ''b,'', label="Power", markevery= self.skip) p2, = par.plot(self.dat.timebase2, self.dat.Temp1, ''r,'', label="Temp 1", markevery= self.skip) p3, = par.plot(self.dat.timebase2, self.dat.Temp2, ''g,'', label="Temp 2", markevery= self.skip) p4, = par.plot(self.dat.timebase2, self.dat.Temp3, ''m,'', label="Temp 3", markevery= self.skip) host.axis["left"].label.set_color(p1.get_color()) # par.axis["right"].label.set_color(p2.get_color()) #host.legend(loc=''lower left'') plt.title(title+" Temperature") leg=host.legend(loc=''lower left'',fancybox=True) #leg.get_frame().set_alpha(0.5) frame = leg.get_frame() frame.set_facecolor(''0.80'') ### make the legend text smaller for t in leg.get_texts(): t.set_fontsize(''small'') ### set the legend text color to the same color as the plots for added ### readability leg.get_texts()[0].set_color(p1.get_color()) leg.get_texts()[1].set_color(p2.get_color()) leg.get_texts()[2].set_color(p3.get_color()) leg.get_texts()[3].set_color(p4.get_color()) if show is True and save is True: plt.show() plt.savefig(''temp.png'') elif show is True and save is False: plt.show() elif show is False and save is True: plt.savefig(''temp.png'') plt.clf() plt.close(fig)

Si ahora corro en una terminal

MyClass.TypicalPlot(save=True, show = False)

Entonces no obtengo ningún error. Lo mismo es cierto para todas mis funciones de trazado.

Si hago una nueva función que hace esto:

def saveAllPlots(self, comments = False): if self.comment is None: comment = False else: comment = True self.TypicalPlot(save=True, show=False, comment=comment) self.AnotherPlot(save=True, show=False) self.AnotherPlot2(save=True, show=False) self.AnotherPlot3(save=True, show=False) ...etc, etc, etc

Luego pasa a través de aproximadamente la mitad de los gráficos y luego aparece "MemoryError: Could not allocation memory for path".


Me encuentro con un problema muy similar una vez. Supongo que matplotlib guarda referencias para cada trama internamente. Dado el siguiente código, crear tres figuras separadas:

import matplotlib.pyplot as plt import numpy as np # block 1 f, ax = plt.subplots(1) plt.plot(np.arange(10), np.random.random(10)) plt.title("first") print ''first'', sys.getrefcount(f), sys.getrefcount(ax) # bock 2 f, ax = plt.subplots(1) plt.plot(np.arange(10), np.random.random(10)+1) plt.title("second") print ''second'', sys.getrefcount(f), sys.getrefcount(ax) # block 3 f, ax = plt.subplots(1) plt.plot(np.arange(10), np.random.random(10)+2) plt.title("third") print ''third'', sys.getrefcount(f), sys.getrefcount(ax) plt.show() print ''after show'', sys.getrefcount(f), sys.getrefcount(ax)

Salida:

first 69 26 second 69 26 third 69 26 after show 147 39

Esto es contrario a la intuición, porque hemos redefinido f y ax varias veces. Con cada bloque, creamos una nueva figura, que puede ser referenciada a través de plt . La creación de otra figura cambia las referencias más plt accesibles por plt . Pero debe haber alguna referencia interna, que permita a plt.show() mostrar todas las figuras. Esas referencias parecen ser persistentes y, por lo tanto, las cifras no serán recopiladas por el gc.

La solución con la que me establecí fue cambiar los datos de la trama. En retrospectiva, fue un mejor enfoque de todos modos:

plt.ion() f, ax = plt.subplots(1) line = ax.plot(np.arange(10), np.random.random(10))[0] plt.title(''first'') plt.show() for i, s in [(2, ''second''), (3, ''third'')]: x = np.arange(10) y = np.random.random(10)+i line.set_data(x, y) ax.set_xlim(np.min(x), np.max(x)) ax.set_ylim(np.min(y), np.max(y)) plt.title(s) plt.draw() raw_input(s)

El único inconveniente es que tienes que mantener la ventana con la figura abierta. Y sin la entrada raw_input el programa solo se ejecutará