2017-01-26 14 views
2

私は問題に直面しており、私はそれを取り除くことはできません。 私はしたい場合、それをreplotにmatplotlibの図を保存するためにピクルパッケージを使用しようとしています。 これまでのところ、Qtウィンドウを開き、lfpViewer.__Init__()の 'if'条件が1(ピクルロード関数をチェックするために0を設定した場合)の場合、いくつかの曲線をプロットする以下のコードがあります。 ツールバーに、現在の図形の.pickleを保存したり、前の図形から.pickleを読み込んだりする2つのボタンを追加しました。Pyqt5環境でPickleでMatplotlibの図を保存するにはどうすればよいですか?

import pickle 
from PyQt5.QtGui import * 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 
import sys 
import os 
import matplotlib 
import numpy as np 
matplotlib.use('Qt5Agg') 
import matplotlib.patches as patches 
from matplotlib.figure import Figure 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar 


class SurfViewer(QMainWindow): 
    def __init__(self, parent=None): 
     super(SurfViewer, self).__init__() 
     self.parent = parent 
     self.centralWidget = QWidget() 
     self.color = self.centralWidget.palette().color(QPalette.Background) 
     self.setCentralWidget(self.centralWidget) 
     self.plotview = QGroupBox(" ") 
     self.layout_plotview = QVBoxLayout() 
     self.mascenelfp = lfpViewer(self) 
     self.layout_plotview.addWidget(self.mascenelfp) 
     self.centralWidget.setLayout(self.layout_plotview) 


class lfpViewer(QGraphicsView): 
    def __init__(self, parent=None): 
     super(lfpViewer, self).__init__(parent) 
     self.parent=parent 
     self.scene = QGraphicsScene(self) 
     self.setScene(self.scene) 
     self.setBackgroundBrush(QBrush(self.parent.color))# self.setBackgroundBrush(QBrush(QColor(200, 200, 200))) 
     self.figure = plt.figure(facecolor=[self.parent.color.red()/255,self.parent.color.green()/255,self.parent.color.blue()/255]) #Figure() 
     self.canvas = FigureCanvas(self.figure) 
     self.toolbar = NavigationToolbar(self.canvas, self) 
     self.save_button = QPushButton() 
     self.save_button.setIcon(QIcon(os.path.join('icons','SaveData.png'))) 
     self.save_button.setToolTip("Save Figure Data") 
     self.toolbar.addWidget(self.save_button) 
     self.save_button.clicked.connect(self.saveFigData) 
     self.load_button = QPushButton() 
     self.load_button.setIcon(QIcon(os.path.join('icons','LoadData.png'))) 
     self.load_button.setToolTip("Load Figure Data") 
     self.toolbar.addWidget(self.load_button) 
     self.load_button.clicked.connect(self.loaddatapickle) 
     if 0: 
      t=np.arange(1000) 
      self.axes_l=self.figure.add_subplot(311) 
      self.axes_l.plot(t, np.sin(2*3.14*100*t)) 
      self.axes_Y=self.figure.add_subplot(312) 
      self.axes_Y.plot(t, np.cos(2*3.14*100*t)) 
      self.axes_Yi=self.figure.add_subplot(313) 
      self.axes_Yi.plot(t, np.tan(2*3.14*100*t)) 


     self.canvas.setGeometry(0, 0, 1600, 500) 
     layout = QVBoxLayout() 
     layout.addWidget(self.toolbar) 
     layout.addWidget(self.canvas) 
     self.setLayout(layout) 

    def loaddatapickle(self): 
     fileName = QFileDialog.getOpenFileName(self,'Load Data', '', 'pickle (*.pickle)') 
     if (fileName[0] == '') : 
      return 
     fileName = str(fileName[0]) 
     filehandler = open(fileName , 'rb') 
     self.figure = pickle.load(filehandler) 
     filehandler.close() 
     self.canvas.draw() 
     self.parent.parent.processEvents() 
     return 

    def saveFigData(self): 
     fileName = QFileDialog.getSaveFileName(self,'Save Figure Data', '', 'pickle (*.pickle)') 
     if (fileName[0] == '') : 
      return 
     fileName = str(fileName[0]) 
     file_pi = open(fileName, 'wb') 
     pickle.dump(self.figure, file_pi, -1) 
     file_pi.close() 
     return 


def main(): 
    app = QApplication(sys.argv) 
    ex = SurfViewer(app) 
    ex.showMaximized() 
    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 

保存はうまくいくようですが(少なくとも、ファイルはありますが)、ロードボタンは絶対に何もしません! ピクルファイルを持っていても、ピクルスが図の正しいバイナリを保存しているかどうかわかりません。なぜなら、ピクルファイルをデバッグモードでロードすると、赤いものがたくさんあるからです。下の画像のための ルック:誰かが何のアイデアを持っている場合は

import pickle 
import matplotlib 
import numpy as np 
matplotlib.use('Qt5Agg') 
import matplotlib.pyplot as plt 

def loaddatapickle(): 
    filehandler = open('test.pickle' , 'rb') 
    figure = pickle.load(filehandler) 
    filehandler.close() 
    return figure 

def saveFigData(figure): 
    file_pi = open('test.pickle', 'wb') 
    pickle.dump(figure , file_pi, 1) 
    file_pi.close() 
    return 


figure = plt.figure() #Figure() 

Save= 0 

if Save==1: 
    t=np.arange(1000) 
    axes_l=figure.add_subplot(311) 
    axes_l.plot(t, np.sin(2*3.14*100*t)) 
    axes_Y=figure.add_subplot(312) 
    axes_Y.plot(t, np.cos(2*3.14*100*t)) 
    axes_Yi=figure.add_subplot(313) 
    axes_Yi.plot(t, np.tan(2*3.14*100*t)) 
    saveFigData(figure) 

else: 

    figure=loaddatapickle() 
    plt.show() 

enter image description here

私はPyQt5せずにコードを実行すると、それは以下のコードで、例えば、正常に動作しますここに行って、教えてください! 良い一日を。

+0

この問題は、pickleがmatplotlib.pylab.Figureの代わりにmatplotlib.figure.Figureを保存していることが原因である可能性があります。だから私はpickleファイルからself.figureをrelaodするときに処理することはできません? – ymmx

+0

タイプ(plt.figure())はmatplotlib.figure.Figureも返しますが、両方とも同じです。 – ImportanceOfBeingErnest

答えて

1

この問題が直面している問題を解決できるかどうかはわかりませんが、試してみましょう。私は言及する必要があります。私はQT5を利用できません。私はPython 2.7とmatplotlib 2.0.0で作業しています。しかし、ここでの解決策は一般的な場合に有効です。

プログラムをpyqt4に適合させて実行すると、酸洗処理がうまく動作することがわかりました。また、unpicklingはエラーを投げなかったので、私はunpickled figureを表示する問題があるかもしれないと思った。

何の図はself.figureに姿をロードするが、に、このアンピックル図でキャンバスを再作成し、新たにレイアウトに追加するだけではなく、ロードできるように判明:もちろん

def loaddatapickle(self): 
    #needed to change some stuff here, since in Qt4 the dialog directly returns a string 
    fileName = QFileDialog.getOpenFileName(self,'Load Data', '') 
    if (fileName == '') : 
     return 
    fileName = str(fileName) 
    filehandler = open(fileName , 'rb') 
    self.figure = pickle.load(filehandler) 
    filehandler.close() 
    # remove the old canvas 
    self.layout().removeWidget(self.canvas) 
    # create a new canvas 
    self.canvas = FigureCanvas(self.figure) 
    # add the new canvas at the position of the old one 
    self.layout().addWidget(self.canvas, 1) 
    self.canvas.draw() 
    self.parent.parent.processEvents() 
    return 

それ新しい図形でキャンバスを直接更新する方が良いでしょうが、それを行う方法はありませんでした。

+0

男、それはハンサムです。それは完全に動作します。 – ymmx

関連する問題