2009-08-08 10 views
6

Stworzyłem małe narzędzie oparte na PyQt w Pythonie, które tworzy wykresy PNG przy użyciu matplotlib, gdy użytkownik kliknie przycisk. Wszystko działa dobrze podczas pierwszych kilku kliknięć, jednak za każdym razem, gdy tworzony jest obraz, rozmiar pamięci aplikacji wzrasta o około 120 MB, co ostatecznie powoduje awarię Pythona.Python wycieka pamięć podczas korzystania PyQt i matplotlib

Jak mogę odzyskać tę pamięć po utworzeniu wykresu? Podaję uproszczoną wersję mojego kod tutaj:

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

plot.savefig („graph.png”) polecenia zdaje się być to, co pochłania pamięć.

Byłbym wdzięczny za każdą pomoc!

Odpowiedz

7

Wygląda na to, że niektóre serwery są przeciekające. Spróbuj jawnie ustawić backend, np.

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

Dzięki! To działało bardzo dobrze. Będę musiał zajrzeć do szczegółów twojej odpowiedzi. –

6

Interfejs pyplot jest przeznaczony do łatwego interaktywnego użycia, ale w przypadku osadzania w aplikacji interfejs API zorientowany obiektowo jest lepszy. Na przykład, pyplot śledzi wszystkie liczby, które utworzyłeś. Twój komputer musi się ich pozbyć, ale może nie zostanie wykonany - spróbuj umieścić go wewnątrz obiektu lub ponownie użyć tego samego obiektu figury.

Zobacz osadzanie matplotlib w aplikacji PyQt4 na stronie this example przy użyciu interfejsu API obiektowego. To więcej pracy, ale ponieważ wszystko jest wyraźne, nie powinno się przeciekać pamięci z powodu zautomatyzowanej automatyzacji Pyplota.