2010-10-19 23 views
11

Estoy diseñando una GUI con PyQt donde necesito mostrar una ventana matplotlib/pylab cuando hago clic en un botón que hace el trazado de los datos de una función que he creado. Es como un tiempo de ejecución utilizado en Matlab. Quiero mantener la ventana matplotlib/pylab como mi ventana cada vez que presiono ese botón.Cómo trazar en mi GUI

Respuesta

17

Aquí hay un ejemplo básico que trazará tres muestras diferentes usando un QThread:

#!/usr/bin/env python 
#-*- coding:utf-8 -*- 

import random 

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg 
from matplotlib.figure import Figure 

from PyQt4 import QtGui, QtCore 

class MatplotlibWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(MatplotlibWidget, self).__init__(parent) 

     self.figure = Figure() 
     self.canvas = FigureCanvasQTAgg(self.figure) 

     self.axis = self.figure.add_subplot(111) 

     self.layoutVertical = QtGui.QVBoxLayout(self) 
     self.layoutVertical.addWidget(self.canvas) 

class ThreadSample(QtCore.QThread): 
    newSample = QtCore.pyqtSignal(list) 

    def __init__(self, parent=None): 
     super(ThreadSample, self).__init__(parent) 

    def run(self): 
     randomSample = random.sample(range(0, 10), 10) 

     self.newSample.emit(randomSample) 

class MyWindow(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(MyWindow, self).__init__(parent) 

     self.pushButtonPlot = QtGui.QPushButton(self) 
     self.pushButtonPlot.setText("Plot") 
     self.pushButtonPlot.clicked.connect(self.on_pushButtonPlot_clicked) 

     self.matplotlibWidget = MatplotlibWidget(self) 

     self.layoutVertical = QtGui.QVBoxLayout(self) 
     self.layoutVertical.addWidget(self.pushButtonPlot) 
     self.layoutVertical.addWidget(self.matplotlibWidget) 

     self.threadSample = ThreadSample(self) 
     self.threadSample.newSample.connect(self.on_threadSample_newSample) 
     self.threadSample.finished.connect(self.on_threadSample_finished) 

    @QtCore.pyqtSlot() 
    def on_pushButtonPlot_clicked(self): 
     self.samples = 0 
     self.matplotlibWidget.axis.clear() 
     self.threadSample.start() 

    @QtCore.pyqtSlot(list) 
    def on_threadSample_newSample(self, sample): 
     self.matplotlibWidget.axis.plot(sample) 
     self.matplotlibWidget.canvas.draw() 

    @QtCore.pyqtSlot() 
    def on_threadSample_finished(self): 
     self.samples += 1 
     if self.samples <= 2: 
      self.threadSample.start() 

if __name__ == "__main__": 
    import sys 

    app = QtGui.QApplication(sys.argv) 
    app.setApplicationName('MyWindow') 

    main = MyWindow() 
    main.resize(666, 333) 
    main.show() 

    sys.exit(app.exec_()) 

image

+0

Estás generando los datos para trazar el interior de su clase (con el generador aleatorio). ¿Es posible pasar los datos desde el exterior? Algo así: 'main = MyWindow (data)' – jonie83

2

Si he entendido bien tiene una aplicación con una interfaz gráfica de usuario y desea trazar un gráfico en una ventana separada que utiliza la interfaz gráfica de usuario. pyqtgraph puede hacer esto muy bien.

primer tipo pip install pyqtgraph en el símbolo del sistema para instalar pyqtgraph

continuación

import pyqtgraph as pg 

    pg.setConfigOption('background', 'w')  # sets background to white             
    pg.setConfigOption('foreground', 'k')  # sets axis color to black 

    pw = pg.plot(x, y, pen='g')    # 1st plot (green)           
    pw.plot(x2, y2, pen='b')     # 2nd plot in same figure (blue) 

    pw.setLabel('bottom', 'x-label')   # x-label 
    pw.setLabel('left', 'y-label')    # y-label 

información más aquí: http://www.pyqtgraph.org/documentation/how_to_use.html

2

Este es el código de user1006989 (mejor respuesta) adaptado a PyQt5 , con suerte será útil para alguien:

Aquí es un ejemplo básico que va a trazar tres muestras diferentes utilizando un QThread:

#!/usr/bin/env python 
#-*- coding:utf-8 -*- 

import random 

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg 
from matplotlib.figure import Figure 

from PyQt5 import QtCore #conda install pyqt 
from PyQt5 import QtWidgets 

class MatplotlibWidget(QtWidgets.QWidget): 
    def __init__(self, parent=None): 
     super(MatplotlibWidget, self).__init__(parent) 

     self.figure = Figure() 
     self.canvas = FigureCanvasQTAgg(self.figure) 

     self.axis = self.figure.add_subplot(111) 

     self.layoutVertical = QtWidgets.QVBoxLayout(self)#QVBoxLayout 
     self.layoutVertical.addWidget(self.canvas) 

class ThreadSample(QtCore.QThread): 
    newSample = QtCore.pyqtSignal(list) 

    def __init__(self, parent=None): 
     super(ThreadSample, self).__init__(parent) 

    def run(self): 
     randomSample = random.sample(range(0, 10), 10) 

     self.newSample.emit(randomSample) 

class MyWindow(QtWidgets.QWidget): 
    def __init__(self, parent=None): 
     super(MyWindow, self).__init__(parent) 

     self.pushButtonPlot = QtWidgets.QPushButton(self) 
     self.pushButtonPlot.setText("Plot") 
     self.pushButtonPlot.clicked.connect(self.on_pushButtonPlot_clicked) 

     self.matplotlibWidget = MatplotlibWidget(self) 

     self.layoutVertical = QtWidgets.QVBoxLayout(self) 
     self.layoutVertical.addWidget(self.pushButtonPlot) 
     self.layoutVertical.addWidget(self.matplotlibWidget) 

     self.threadSample = ThreadSample(self) 
     self.threadSample.newSample.connect(self.on_threadSample_newSample) 
     self.threadSample.finished.connect(self.on_threadSample_finished) 

    @QtCore.pyqtSlot() 
    def on_pushButtonPlot_clicked(self): 
     self.samples = 0 
     self.matplotlibWidget.axis.clear() 
     self.threadSample.start() 

    @QtCore.pyqtSlot(list) 
    def on_threadSample_newSample(self, sample): 
     self.matplotlibWidget.axis.plot(sample) 
     self.matplotlibWidget.canvas.draw() 

    @QtCore.pyqtSlot() 
    def on_threadSample_finished(self): 
     self.samples += 1 
     if self.samples <= 2: 
      self.threadSample.start() 

if __name__ == "__main__": 
    import sys 

    app = QtWidgets.QApplication(sys.argv) 
    app.setApplicationName('MyWindow') 

    main = MyWindow() 
    main.resize(666, 333) 
    main.show() 

    sys.exit(app.exec_())