Pergunta

Eu criei um pequeno utilitário baseado PyQt em Python que cria gráficos PNG usando matplotlib quando um usuário clica em um botão. Tudo funciona bem durante os primeiros alguns cliques, no entanto, cada vez que uma imagem é criada, consumo de memória do aplicativo cresce cerca de 120 MB, eventualmente, bater Python completamente.

Como posso recuperar essa memória depois de um gráfico é criado? Eu incluí uma versão simplificada do meu código aqui:

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

O plot.savefig ( 'graph.png') de comando parece ser o que está devorando a memória.

Eu apreciaria muito qualquer ajuda!

Foi útil?

Solução

Parece que alguns backends estão vazando memória. Tente definir o seu backend explicitamente, por exemplo.

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

Outras dicas

A interface pyplot é destinado para uso interativo fácil, mas para incorporar em um aplicativo da API orientada a objeto é melhor. Por exemplo, pyplot mantém o controle de todas as figuras que você criou. Seu plot.close(figure) deve se livrar deles, mas talvez ele não seja executado -. Tentar colocá-lo dentro finally ou reutilizar a mesma figura objeto

este exemplo de incorporar matplotlib em uma aplicação PyQt4 usando o object- API orientada. É mais trabalho, mas uma vez que tudo é explícito, você não deve ter vazamentos de memória a partir da automação por trás das cenas que pyplot faz.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top