Вопрос

Я создал небольшую утилиту на основе 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') поглощает память.

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

Это было полезно?

Решение

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

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

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top