Python的Matplotlib绘图嵌入PyQt5界面(GUI)方法

Python的Matplotlib绘图嵌入PyQt5界面(GUI)方法

利用业余时间刚刚学习Python两个月左右,涉及工作中将计算数据图形化,最后又想将图形插入GUI。

先记一下流水账。首先,针对工作任务完成了面向过程编程,用matplotlib的plot将计算结果绘制成曲线图。其次,学习了tkinter实现GUI,操作比较麻烦,又转学PyQt5的Qt Designer。然后,学习了面向对象编程,将前期的面向过程编程转化为面向对象,同时完成了PyQt5的GUI。

但是,计算结果的曲线图是与GUI分离的,没有嵌入到GUI之中。于是,想到将绘制成的曲线图在GUI显示,网上搜索到2种方法。下面分别介绍:

1.反复创建绘图:每次调用,删除之前的绘图PyQt控件,创建新的绘图PyQt控件:

官方源码:user_interfaces example code: embedding_in_qt5.py — Matplotlib 2.0.2 documentation

2.只创建一次绘图PyQt控件:每次调用,清空之前的曲线,重画新的曲线:

官方源码:Embedding in Qt — Matplotlib 3.4.3 documentation

第1种方法的实现及遇到的问题。最开始,用了第1种方法,实现了功能,没有任何问题。但是,在增加一项功能后,绘图刷新出问题了。故事的发生是这样的:在GUI中增加一个文本控件,将本来在计算过程中用print()命令输出到CMD控制台的数据显示到该文本控件中,也即重定向输出;绘制的曲线图总是不显示最后调用的方法绘制的曲线,在程序里将该方法提到其它方法前面,则该方法及其后的方法所绘制的曲线都不显示,但确实都调用执行了,很是奇怪!

第2种方法的实现及效果。基于上述情况,只好转而用第2种方法。修改脚本后,可以绘制出第一个画面,但不更新后续画面。通过查找,发现第2种方法的官方源码中,只画一条曲线:

self._line, = self._dynamic_ax.plot(t, np.sin(t + time.time()))

更新也只针对这一条曲线进行更新:

self._line.set_data(t, np.sin(t + time.time()))

self._line.figure.canvas.draw()

而本人的脚本,是绘制多条曲线组成的图。所以,不能用官方源码的方式,应该用更新子图的方式,即改用了下面的语句:

self._dynamic_ax.figure.canvas.draw()

修改后运行程序,画面是更新了,但是,旧的画面还在。于是,在调用绘图方法前,增加下面的子图清空语句:

self._dynamic_ax.clear()

这样修改后,脚本运行正常,重定向输出也没有问题,达到了之前的预期效果。

写在最后:这里只是记录了一下本次解决问题的过程,没有写实现原理;相关技术文章,可在本站搜索,非常多且好。本站有很多大牛写的相关文章,非常非常棒,本人遇到问题,首先就是到本站找解决办法。这次的问题解决,也是在本站找到的。希望本文能对同本人一样的初学者有一点点帮助,也算回馈本站吧。

谢谢各位客官耐心读到这里!!!

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PyQt5界面嵌入Matplotlib实际上非常简单。以下是代码示例,它将Matplotlib嵌入到一个PyQt5窗口应用程序中: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QHBoxLayout, QWidget, QPushButton from PyQt5.QtGui import QIcon from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure class PlotCanvas(FigureCanvas): def __init__(self, parent=None, width=5, height=4, dpi=100): fig = Figure(figsize=(width, height), dpi=dpi) self.axes = fig.add_subplot(111) FigureCanvas.__init__(self, fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt5 & Matplotlib Demo") self.setGeometry(100, 100, 800, 600) # Create the button to update the plot update_button = QPushButton("Update Plot", self) update_button.resize(100, 25) update_button.move(10, 10) update_button.clicked.connect(self.update_plot) # Create the canvas to display the plot canvas = PlotCanvas(self, width=5, height=4) canvas.move(0, 100) # Create a layout for the window layout = QVBoxLayout() layout.addWidget(update_button) layout.addWidget(canvas) # Create a central widget and set the layout central_widget = QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) self.update_plot() def update_plot(self): # Clear the figure self.canvas.axes.clear() # Create some data to plot x = [1, 2, 3, 4, 5] y = [3, 5, 1, 7, 9] # Plot the data self.canvas.axes.plot(x, y) # Update the canvas self.canvas.draw() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ``` 这段代码首先定义了一个名为PlotCanvas的类,它是一个受Matplotlib支持的Qt小部件,并用于在Matplotlib图形上绘制。接下来,MainWindow类继承自QMainWindow并定义了一个PyQt5应用程序的主窗口。在构造函数中,我们创建了一个用于更新绘图的按钮,以及一个用于在其中绘制Matplotlib图形的PlotCanvas对象。然后,我们将两个控件添加到窗口布局中并显示窗口。最后,在update_plot方法中,我们定义了要绘制的数据以及绘图命令,然后将其呈现到Matplotlib图形上并更新窗口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值