如何在我的 GUI 上绘图

Posted

技术标签:

【中文标题】如何在我的 GUI 上绘图【英文标题】:How to plot on my GUI 【发布时间】:2011-04-27 16:40:14 【问题描述】:

我正在设计一个带有 PyQt 的 GUI,当我单击一个按钮时,我需要显示一个 matplotlib/pylab 窗口,该按钮从我创建的函数中绘制数据图。它就像在 Matlab 中使用的运行时。每次按下该按钮时,我都希望将 matplotlib/pylab 窗口保留为我的窗口。

【问题讨论】:

【参考方案1】:

这是一个基本示例,它将使用 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_())

【讨论】:

您正在生成用于在您的班级内绘图的数据(使用随机生成器)。是否可以从外部传递数据。类似的东西:main = MyWindow(data)【参考方案2】:

这是来自 user1006989(最佳答案)的代码,适用于 PyQt5,希望它对某人有用:

这是一个基本示例,它将使用 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_())

【讨论】:

【参考方案3】:

Eli Bendersky 编写了一个在 PyQt 中使用 matplotlib 的代码示例:http://eli.thegreenplace.net/2009/01/20/matplotlib-with-pyqt-guis/

【讨论】:

【参考方案4】:

将 Matplotlib 与 PyQt 集成需要一些工作。这是一个例子: http://sourceforge.net/mailarchive/message.php?msg_id=29086544

但是,有一些专门围绕 PyQt 设计的绘图库:

pyqwt(编辑:不再维护) guiqwt pyqtgraph

【讨论】:

【参考方案5】:

如果我对您的理解正确,您有一个带有 GUI 的应用程序,并且您想在一个单独的窗口中绘制图形,而不是 GUI 使用的窗口。 pyqtgraph 可以很好地做到这一点。

首先在命令行输入pip install pyqtgraph安装pyqtgraph

然后

   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

更多信息在这里: http://www.pyqtgraph.org/documentation/how_to_use.html

【讨论】:

以上是关于如何在我的 GUI 上绘图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JPanel 中绘图? (摇摆/图形Java)

Python GUI 中的实时绘图

如何仅清除qyqt5中的图?

如何在填充的GUI轴中使用“ButtonDownFcn”?

如何计算jtable中的数据并显示在我的gui底部

如何在标准按钮 WinApi 上绘图