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()
这样修改后,脚本运行正常,重定向输出也没有问题,达到了之前的预期效果。
写在最后:这里只是记录了一下本次解决问题的过程,没有写实现原理;相关技术文章,可在本站搜索,非常多且好。本站有很多大牛写的相关文章,非常非常棒,本人遇到问题,首先就是到本站找解决办法。这次的问题解决,也是在本站找到的。希望本文能对同本人一样的初学者有一点点帮助,也算回馈本站吧。
谢谢各位客官耐心读到这里!!!