Python在使用PyQt和matplotlib时泄漏内存

问题描述:

我已经在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”)命令似乎是什么吞噬内存。

我非常感谢任何帮助!

看来,一些后端正在泄漏内存。尝试明确设置后端,例如

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

谢谢!这工作得很好。我将不得不查看你的答案的更多细节。 – 2009-08-08 17:32:34

pyplot接口是为了方便交互使用,但为了嵌入应用程序,面向对象的API更好。例如,pyplot会跟踪您创建的所有数字。你的plot.close(figure)应该摆脱它们,但也许它不会被执行 - 尝试将其放入finally或重复使用相同的数字对象。

请参阅this example使用面向对象的API将matplotlib嵌入到PyQt4应用程序中。这是更多的工作,但是因为一切都是明确的,所以你不应该从pyplot所做的幕后自动化中获得内存泄漏。