Pregunta

He creado una pequeña utilidad basada en Python PyQt que crea gráficos PNG utilizando matplotlib cuando un usuario hace clic en un botón. Todo funciona bien durante los primeros pocos clics, sin embargo, cada vez que se crea una imagen, huella de la memoria de la aplicación crece alrededor de 120 MB, finalmente estrellarse Python completo.

¿Cómo puedo recuperar esta memoria después se crea un gráfico? He incluido una versión simplificada de mi código aquí:

import datetime as dt
from datetime import datetime 
import os
import gc
# For Graphing
import matplotlib
from pylab import figure, show, savefig
from matplotlib import figure as matfigure
from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, DayLocator
from matplotlib.ticker import MultipleLocator
import matplotlib.pyplot as plot
import matplotlib.ticker as ticker
# For GUI
import sys
from PyQt4 import QtGui, QtCore

class HyperGraph(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setWindowTitle('Title')
        self.create_widgets()

    def create_widgets(self):
        grid = QtGui.QGridLayout()
        self.generate_button = QtGui.QPushButton("Generate Graph", self)
        grid.addWidget(self.generate_button, 1, 1)
        QtCore.QObject.connect(self.generate_button, QtCore.SIGNAL("clicked()"), self.generate_graph)

    def generate_graph(self):
        try:
            fig = figure()
            ax = fig.add_axes([1,1,1,1])

            # set title
            ax.set_title('Title')

            # configure x axis
            plot.xlim(dt.date.today() - dt.timedelta(days=180), dt.date.today())
            ax.set_xlabel('Date')
            fig.set_figwidth(100)

            # configure y axis
            plot.ylim(0, 200)
            ax.set_ylabel('Price')
            fig.set_figheight(30)

            # export the graph to a png file
            plot.savefig('graph.png')

        except:
            print 'Error'

        plot.close(fig)
        gc.collect()

app = QtGui.QApplication(sys.argv)
hyper_graph = HyperGraph()
hyper_graph.show()
sys.exit(app.exec_())

El plot.savefig ( 'graph.png') de comandos parece ser lo que está engullendo la memoria.

Te agradecería enormemente cualquier ayuda!

¿Fue útil?

Solución

Parece que algunos backends son fugas de memoria. Pruebe a establecer su base de forma explícita, por ejemplo.

import matplotlib
matplotlib.use('Agg') # before import pylab
import pylab

Otros consejos

La interfaz pyplot está destinado para uso interactivo fácil, pero para incrustar en una aplicación de la API orientada a objetos es mejor. Por ejemplo, pyplot mantiene un registro de todas las cifras que ha creado. Su plot.close(figure) debe deshacerse de ellos, pero tal vez no se ejecuta -. Trate de poner dentro finally o reutilizar la misma figura objeto

Ver este ejemplo de incrustar matplotlib en una aplicación PyQt4 usando el objeto- API orientada. Es más trabajo, pero ya que todo es explícito, no debe someterse a pérdidas de memoria desde la automatización de detrás de las escenas que pyplot hace.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top