Python memory leaks using PyQt and matplotlib

I created a small PyQt-based utility in Python that creates PNG graphics using matplotlib when the user clicks a button. Everything works well for the first few clicks, however, every time an image is created, the application’s memory is increased by about 120 MB, eventually all Python crashes.

How to recover this memory after creating a graph? I have included a simplified version of my code here:

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

The plot.savefig ('graph.png') command seems to absorb memory.

I am very grateful for any help!

+6
python matplotlib memory-leaks pyqt
source share
2 answers

Some servers seem to leak memory. Try to explicitly install your server, for example

 import matplotlib matplotlib.use('Agg') # before import pylab import pylab 
+7
source share

The pyplot interface is designed for easy interactive use, but an object-oriented API is better for embedding into an application. For example, pyplot keeps track of all your drawings. Your plot.close(figure) should get rid of them, but it may not be executed - try placing it inside finally or reusing the same shape object.

See this example of embedding matplotlib in a PyQt4 application using an object-oriented API. This works more, but since everything is explicit, you should not get memory leaks from the backstage automation that pyplot does.

+6
source share

All Articles