2017-01-26 12 views
2

У меня проблема, и я не могу избавиться от нее. Я пытаюсь использовать пакет Pickle, чтобы сохранить фигуру matplotlib для ее замены, если захочу. До сих пор у меня есть код ниже, который открывает окно Qt и выстраивает в нем некоторые кривые, если условие «если» в lfpViewer.__Init__() равно 1 (я положил 0 только для проверки функции загрузки рассола). Итак, я добавил на панель инструментов две кнопки, где я могу сохранить .pickle текущей фигуры или загрузить .pickle с предыдущего рисунка.Как сохранить фигуру Matplotlib с Pickle в среде Pyqt5?

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

Сохранение похоже работает (ну, по крайней мере, у меня есть файл), но кнопка загрузки абсолютно ничего не делает! Даже если у меня есть .pickle-файл, я не знаю, если pickle сохранить правильный двоичный код, потому что, когда я загружаю файл pickle в режиме отладки, я получаю много красных вещей. Посмотрите на рисунке ниже:

enter image description here

Если я код без PyQt5, он отлично работает, например, на код ниже:

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

Если кто-то есть идея о том, что здесь, пожалуйста, скажите мне! Имейте славный день.

+0

Проблема может быть связана с тем, что рассол сохраняет матрицу. Настроить вместо matplotlib.pylab.Figure. Так что его нельзя обрабатывать, когда я переустанавливаю self.figure из файла pickle? – ymmx

+0

type (plt.figure()) возвращает matplotlib.figure.Figure также, они оба одинаковы. – ImportanceOfBeingErnest

ответ

1

Я не могу быть уверен, что это решает проблему, с которой вы сталкиваетесь, но давайте попробуем. Я должен упомянуть, у меня нет QT5, и я работаю с python 2.7 и matplotlib 2.0.0. Но решение здесь может быть справедливо для общих случаев.

При адаптации программы к pyqt4 и ее запуске я узнал, что травление прекрасно работает. Кроме того, рассыпание не вызывало ошибок, поэтому я подозревал, что может возникнуть проблема с отображением незакрашенной фигуры.

Что же получается разрешить загрузку цифра не только нагрузить фигуру в self.figure но воссоздать холст с этой unpickled фигуры и вновь добавить его в макет:

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

 Смежные вопросы

  • Нет связанных вопросов^_^