2016-12-05 24 views
1

基本的にQtデザイナでMatplotlib GUIを構築しました。this tutorialです。私はpython 3.5.2とpyqt 5.6.0を使用しています。下記のコードは動作しています。しかし、プロットを変更すると、システムによって使用されるメモリが増加します。少なくとも、Windows 10のタスクマネージャによると。これを少しでも良く再現するには、プロットコマンドで使用されるランダムな値の数を増やすことができます。 rmmppl関数内のself.canvas.close()コマンドは、実際に使用されているメモリを解放するには不十分です。matplotlibをPyQt5 GUIに埋め込むときのメモリリーク

メモリ使用量の増加を防ぐにはどうすればよいですか?

編集:ここではGUIのScreenshotがある

from PyQt5 import QtCore, QtGui, QtWidgets 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas, 
NavigationToolbar2QT as NavigationToolbar) 
import window 
import numpy as np 


class Plotter(QtWidgets.QMainWindow, window.Ui_MainWindow): 
    def __init__(self): 
     super(Plotter, self).__init__() 
     self.setupUi(self) 
     self.fig_dict = {}  
     self.mplfigs.itemClicked.connect(self.changefig) 

    def addmpl(self, fig): 
     self.canvas = FigureCanvas(fig) 
     self.mplvl.addWidget(self.canvas) 
     self.canvas.draw() 
     self.toolbar = NavigationToolbar(self.canvas,self.mplwindow, coordinates = True) 
     self.mplvl.addWidget(self.toolbar) 

    def rmmppl(self): 
     self.mplvl.removeWidget(self.canvas) 
     self.canvas.close() 
     self.mplvl.removeWidget(self.toolbar) 
     self.toolbar.close() 

    def addfig(self, name, fig): 
     self.fig_dict[name]=fig 
     self.mplfigs.addItem(name) 

    def changefig(self,item): 
     text = item.text() 
     self.rmmppl() 
     self.addmpl(self.fig_dict[text]) 



def main(): 
    import sys 

    fig1 = Figure() 
    ax1f1= fig1.add_subplot(111) 
    ax1f1.plot(np.random.rand(5)) 

    fig2 = Figure() 
    ax1f2 = fig2.add_subplot(121) 
    ax1f2.plot(np.random.rand(5)) 
    ax1f2 = fig2.add_subplot(122) 
    ax1f2.plot(np.random.rand(10))  

    app=QtWidgets.QApplication(sys.argv) 
    main=Plotter() 
    main.addmpl(fig1) 
    main.addfig('Figure 1', fig1) 
    main.addfig('Figure 2', fig2) 
    main.show() 

    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 

基本的なGUI構造であるwindow.py:

from PyQt5 import QtCore, QtGui, QtWidgets 

class Ui_MainWindow(object): 
    def setupUi(self, MainWindow): 
     MainWindow.setObjectName("MainWindow") 
     MainWindow.resize(640, 432) 
     self.centralwidget = QtWidgets.QWidget(MainWindow) 
     self.centralwidget.setObjectName("centralwidget") 
     self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) 
     self.horizontalLayout.setObjectName("horizontalLayout") 
     self.mplwindow = QtWidgets.QWidget(self.centralwidget) 
     sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) 
     sizePolicy.setHorizontalStretch(0) 
     sizePolicy.setVerticalStretch(0) 
     sizePolicy.setHeightForWidth(self.mplwindow.sizePolicy().hasHeightForWidth()) 
     self.mplwindow.setSizePolicy(sizePolicy) 
     self.mplwindow.setObjectName("mplwindow") 
     self.mplvl = QtWidgets.QVBoxLayout(self.mplwindow) 
     self.mplvl.setContentsMargins(0, 0, 0, 0) 
     self.mplvl.setObjectName("mplvl") 
     self.horizontalLayout.addWidget(self.mplwindow) 
     self.mplfigs = QtWidgets.QListWidget(self.centralwidget) 
     sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding) 
     sizePolicy.setHorizontalStretch(0) 
     sizePolicy.setVerticalStretch(0) 
     sizePolicy.setHeightForWidth(self.mplfigs.sizePolicy().hasHeightForWidth()) 
     self.mplfigs.setSizePolicy(sizePolicy) 
     self.mplfigs.setMaximumSize(QtCore.QSize(200, 16777215)) 
     self.mplfigs.setMinimumSize(QtCore.QSize(200, 0)) 
     self.mplfigs.setObjectName("mplfigs") 
     self.horizontalLayout.addWidget(self.mplfigs) 
     MainWindow.setCentralWidget(self.centralwidget) 
     self.menubar = QtWidgets.QMenuBar(MainWindow) 
     self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 31)) 
     self.menubar.setObjectName("menubar") 
     MainWindow.setMenuBar(self.menubar) 
     self.statusbar = QtWidgets.QStatusBar(MainWindow) 
     self.statusbar.setObjectName("statusbar") 
     MainWindow.setStatusBar(self.statusbar) 

     self.retranslateUi(MainWindow) 
     QtCore.QMetaObject.connectSlotsByName(MainWindow) 

    def retranslateUi(self, MainWindow): 
     _translate = QtCore.QCoreApplication.translate 
     MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) 

答えて

3

私はLinux上でコードを実行していると私は観察しています同じメモリリーク。これで 試してみてください:

インポートガベージコレクタで:

import gc 

その後、あなたのrmmppl方法を変更します。ここでは

def rmmppl(self): 
    self.canvas.close() 
    self.canvas.deleteLater() 
    self.toolbar.close() 
    self.toolbar.deleteLater() 
    gc.collect() 

は、このソリューションは、私の問題を解決しdeleteLater QObject Class Documentation

+0

のためのドキュメントです、ありがとう! –

関連する問題