Утечка памяти в Python при использовании PyQt и matplotlib - PullRequest
6 голосов
/ 08 августа 2009

Я создал небольшую утилиту на основе PyQt в Python, которая создает PNG-графики с использованием matplotlib, когда пользователь нажимает кнопку. Все работает хорошо в течение первых нескольких кликов, однако каждый раз, когда создается изображение, объем памяти приложения увеличивается до 120 МБ, что в итоге приводит к краху 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') поглощает память.

Буду очень признателен за любую помощь!

Ответы [ 2 ]

7 голосов
/ 08 августа 2009

Похоже, что некоторые серверы теряют память. Попробуйте установить бэкэнд явно, например,

import matplotlib
matplotlib.use('Agg') # before import pylab
import pylab
6 голосов
/ 10 августа 2009

Интерфейс pyplot предназначен для простого интерактивного использования, но для встраивания в приложение объектно-ориентированный API лучше. Например, pyplot отслеживает все созданные вами фигуры. Ваш plot.close(figure) должен избавиться от них, но, возможно, он не будет выполнен - ​​попробуйте поместить его внутрь finally или повторно использовать тот же объект фигуры.

См. этот пример встраивания matplotlib в приложение PyQt4 с использованием объектно-ориентированного API. Это больше работы, но так как все ясно, вы не должны получать утечки памяти из-за закулисной автоматизации, которую делает pyplot.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...