如何在我的 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 上绘图的主要内容,如果未能解决你的问题,请参考以下文章