2009-08-08 60 views
6

Pythonで小さなPyQtベースのユーティリティを作成しました。これは、ユーザがボタンをクリックしたときにmatplotlibを使ってPNGグラフを作成します。最初の数回のクリックですべてがうまく動作しますが、イメージが作成されるたびにアプリケーションのメモリフットプリントが約120 MB増加し、最終的にはPythonが完全にクラッシュします。PyQtとmatplotlibを使用しているときにPythonがリークするメモリ

グラフを作成した後でこのメモリを回復するにはどうすればよいですか?

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」)コマンドがメモリをgobblingているもののようだ:私はここに私のコードの簡易版を用意しました。

大変助かりました!

答えて

7

バックエンドによってはメモリがリークしているようです。明示的にバックエンドを設定してみてください。

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

ありがとうございます!これは非常にうまくいった。私はあなたの答えの詳細を調べなければならないでしょう。 –

6

pyplotインターフェイスは簡単に対話的に使用するためのものですが、アプリケーションに埋め込むためにオブジェクト指向のAPIが優れています。たとえば、pyplotは、作成したすべての図を追跡します。あなたのplot.close(figure)であるべきですが、実行されないかもしれません - finallyの中に入れたり、同じFigureオブジェクトを再利用してみてください。

オブジェクト指向のAPIを使用してPyQt4アプリケーションにmatplotlibを埋め込むことについては、this exampleを参照してください。それ以上の作業ですが、すべてが明示的なので、pyplotが行う背後のオートメーションからメモリリークを取得すべきではありません。

関連する問題