pyqt5+matplotlib结合使用,以及完美解决其出现的图像不更新问题

问题描述:

做一个项目的小软件的时候需要利用计算出来的数值绘制图像,搜索之后发现可以利用matplotlib.backends.backend_qt5agg中的FigureCanvasQTAgg类实现pyqt5与matplotlib的结合,并成功的绘制的图像,但是当我重新输入一组数据后,发现图像不能够更新,即不能利用新的数据重新绘制图像。


pyqt5+matplotlib:

项目不便展示,因此在这里举一个小例子

1.首先用qtdesigner创建一个界面,注意红箭头指的是一个GroupBox,用来给图像提供画板。

2.然后使用Eric6编译窗体,Eric6+pyqt5结合非常好用,当然不用这个IDE也可以将ui文件转化为python代码,具体操作自行百度。

 3.生成代码如下图,运行之后就是一个界面,没有功能。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'C:\Users\jxq\Desktop\boke\window_UI.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(584, 496)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralWidget)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.groupBox = QtWidgets.QGroupBox(self.centralWidget)
        self.groupBox.setMinimumSize(QtCore.QSize(0, 400))
        self.groupBox.setObjectName("groupBox")
        self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        self.horizontalLayout.setContentsMargins(0, -1, -1, -1)
        self.horizontalLayout.setSpacing(6)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButton = QtWidgets.QPushButton(self.centralWidget)
        self.pushButton.setMaximumSize(QtCore.QSize(150, 40))
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QtWidgets.QPushButton(self.centralWidget)
        self.pushButton_2.setMaximumSize(QtCore.QSize(150, 40))
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(self.centralWidget)
        self.pushButton_3.setMaximumSize(QtCore.QSize(150, 40))
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout.addWidget(self.pushButton_3)
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
        self.horizontalLayout_2.addLayout(self.gridLayout)
        MainWindow.setCentralWidget(self.centralWidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "GroupBox"))
        self.pushButton.setText(_translate("MainWindow", "绘制正弦函数"))
        self.pushButton_2.setText(_translate("MainWindow", "绘制余弦函数"))
        self.pushButton_3.setText(_translate("MainWindow", "清空图形"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

 4.具体实现功能需要新建一个Main.py文件,使用Eric6可以快速生成对话框代码,手写也可,文件代码如下,此时点击“绘制正弦图像”按键即可绘制图像,代码讲解写在注释上。

# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QMainWindow, QGridLayout, QApplication
from Ui_window_UI import Ui_MainWindow
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import numpy as np
from matplotlib.figure import Figure
import sys


#这个类用来画图
class Figure_Canvas(FigureCanvas):
    def __init__(self,width=4,height=3,dpi=100):
        self.fig=Figure(figsize=(width,height),dpi=100)#设置长宽以及分辨率
        super(Figure_Canvas,self).__init__(self.fig)
        self.ax=self.fig.add_subplot(111)#创建axes对象实例,这个也可以在具体函数中添加
        
#这是主界面
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.Plot_Sin)#按键连接Plot_Sin函数
    
    def Plot(self):#这里是绘图的关键
         self.plot_Figure = Figure_Canvas()#创建实例
         self.plot_FigureLayout = QGridLayout(self.groupBox)#利用栅格布局将图像与画板连接
         self.plot_FigureLayout.addWidget(self.plot_Figure)
    
    def Plot_Sin(self):
         self.Plot()
         self.x = np.linspace(0,2*np.pi,240,endpoint=True)
         self.y = np.sin(self.x)
         self.plot_Figure.ax.plot(self.x, self.y)#绘图
    
   
       
if __name__ == "__main__":
    
    app = QApplication(sys.argv)
    ui = MainWindow()
    ui.show()
    sys.exit(app.exec_())

5.至此已经完成 pyqt5与matplotlib的结合


图像更新问题:

与上文类似,接着写了cos函数的代码,把这行代码写在MainWindow类的初始化函数中,再添加一个Plot_Cos函数,此时按道理点击余弦按钮应该显示显示余弦图像,但是实际测试并未更新。

self.pushButton_2.clicked.connect(self.Plot_Cos)
    def Plot_Cos(self):
         self.Plot()
         self.x = np.linspace(0,2*np.pi,240,endpoint=True)
         self.y = np.cos(self.x)
         self.plot_Figure.ax.plot(self.x, self.y)

解决方案:

为了解决这个问题设置了清空图像按键,函数如下,删除布局代码不可省,不然还是无法更新。

 self.pushButton_3.clicked.connect(self.ReSet)
   def ReSet(self):
         self.plot_Figure.deleteLater()#删除图像对象
         self.plot_FigureLayout.deleteLater()#删除布局

解决后效果如下

1.单击“绘制正弦函数”,出先正弦函数图像

2.单击“清空图形”,图像被清空

3.再点绘制“余弦函数”,图像成功刷新

ps:“清空图像”无法连续点击两次,因为已经删除了画图对象和布局了,再删会报错,实际应用可以嵌入在绘图函数中而不用单独设置清除键,也可设置一个flag来检测是否存在画图对象以及布局,防止重复删除报错。

pss:import sip ,使用sip.delete(),删除那两个对象也可以实现更新

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jiang_Tesla

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值