2009-08-08 16 views
6

我已經在Python中創建了一個基於PyQt的小型實用程序,它可以在用戶單擊按鈕時使用matplotlib創建PNG圖。在最初的幾次點擊過程中,一切正常,但每次創建圖像時,應用程序的內存佔用量將增加大約120 MB,最終會導致Python崩潰。Python在使用PyQt和matplotlib時泄漏內存

如何在創建圖形後恢復此內存?我已經包括了我的代碼的簡化版本在這裏:

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」)命令似乎是什麼吞噬內存。

我非常感謝任何幫助!

回答

7

看來,一些後端正在泄漏內存。嘗試明確設置後端,例如

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

謝謝!這工作得很好。我將不得不查看你的答案的更多細節。 – 2009-08-08 17:32:34

6

pyplot接口是爲了方便交互使用,但爲了嵌入應用程序,面向對象的API更好。例如,pyplot會跟蹤您創建的所有數字。你的plot.close(figure)應該擺脫它們,但也許它不會被執行 - 嘗試將其放入finally或重複使用相同的數字對象。

請參閱this example使用面向對象的API將matplotlib嵌入到PyQt4應用程序中。這是更多的工作,但是因爲一切都是明確的,所以你不應該從pyplot所做的幕後自動化中獲得內存泄漏。