PyQt5在窗口上显示动态图表

2022-08-27 13:59:48

在某些情况下,可能需要在窗口界面中显示动态图表来体现数据的更新变化。本人正好在做项目中碰到了这种情况,需要动态显示一个甘特图,就以此为例告诉大家怎么实现。首先,直接上完整代码:

import sysimport matplotlibimport datetime

matplotlib.use("Qt5Agg")from PyQt5import QtCorefrom PyQt5.QtWidgetsimport QApplication,  QVBoxLayout, QSizePolicy, QWidgetfrom matplotlib.backends.backend_qt5aggimport FigureCanvasQTAggas FigureCanvasfrom matplotlib.figureimport Figureimport matplotlib.pyplotas pltclassMyMplCanvas(FigureCanvas):def__init__(self, parent=None, width=5, height=4, dpi=100):# 配置中文显示
        plt.rcParams['font.family']=['SimHei']# 用来正常显示中文标签
        plt.rcParams['axes.unicode_minus']=False# 用来正常显示负号

        self.fig= Figure(figsize=(width, height), dpi=dpi)# 新建一个figure
        self.axes= self.fig.add_subplot(111)# 建立一个子图,如果要建立复合图,可以在这里修改

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                                   QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)'''启动显示动态图'''defDisplay_dynamic_gantt(self,*args,**kwargs):# 设置一个时间对象
        timer= QtCore.QTimer(self)# 连接需要动态刷新的方法函数
        timer.timeout.connect(self.update_figure)# 表示每1秒钟刷新一次
        timer.start(1000)'''绘制动态图方法函数,可以在这里定义自己的绘图逻辑'''defupdate_figure(self):# 每次重新绘制前需要清楚之前绘制的内容# 获取当前的系统时间
        now= datetime.datetime.now()
        self.axes.clear()
        l1= now.second*1.8if l1>60:
            l1=60
        l2= now.second*1.5if l2>60:
            l2=60# 画甘特图
        self.axes.barh((1,2,3,4,5),(0+ now.second,0+ l1,0+ now.second,0+ l2,0+ now.second),0.5,(0,60,120,180,240))
        self.axes.set_yticks(range(1,6,1))
        self.axes.set_yticklabels(('a','b','c','d','e'))
        self.axes.set_xticks(range(0,300,60))
        self.axes.set_xticklabels((u'周一', u'周二', u'周三', u'周四', u'周五'))
        self.draw()classMatplotlibWidget(QWidget):def__init__(self, parent=None):super(MatplotlibWidget, self).__init__(parent)
        self.initUi()definitUi(self):
        self.layout= QVBoxLayout(self)
        self.mpl= MyMplCanvas(self, width=5, height=4, dpi=100)# 初始化显示甘特图
        self.mpl.Display_dynamic_gantt()
        self.layout.addWidget(self.mpl)if __name__=='__main__':
    app= QApplication(sys.argv)
    ui= MatplotlibWidget()
    ui.show()
    sys.exit(app.exec_())

代码呢,我只挑重要的讲,主要是为了给想快速实现的小白看的,没必要把全部代码搞懂!
首先,大家可以直接复制整个代码作为模板(因为我就是这样的嘻嘻),主要可以自行修改的部分有两个:启动显示动态图、绘制动态图方法函数,其余部分都可以不用管,直接用就是!
一是启动显示动态图部分,这个部分定义了一个函数Display_dynamic_gantt(),这个主要就是用来显示动态的图表,其中里面设置了一个QTimer对象,这个可以用来更新函数,timer.timeout.connect()就是用来连接需要更新的函数的, timer.start(1000)表示开始动态更新,每秒更新一次连接括号里的函数。
二是绘制动态图方法函数,这个部分定义了需要更新的函数update_figure(),也就是绘制动态甘特图的函数。这里我用到了datetime方法,它可以获取当前的系统时间,年月日、时分秒都可以,因为要实现更新,就得需要一个更新的条件,即每次调用都会产生不同的数据,那么最简单的方式就是获取系统时间了(有的人用的随机函数也可以,但是得到的数据是不确定的,所以不是很适用)。接着就是调用self.axes.clear(),这个很重要,因为你在每次绘制之前不清除上一次的结果,就会保留之前的绘制图表,结果可想而知!时间这里我获取的是秒,这样可以更新快一点。然后就是绘制图表的部分了,这里大家可以绘制自己想要的图表,我已甘特图为例,具体怎么画图的大家可以看我之前写的文章Matplotlib.pyplot中的冷门方法。我在甘特图的宽度上加了系统时间的秒数,所以每次更新该函数后都会重新绘制一次甘特图,而每一条的宽度就是当前的系统时间的秒的大小。同时我也给几个条形设置了不同的速度,比如l1就是1.8倍速,同时设置了范围不能超过60。
总之把想绘制的图像以及更新的效果设置好就了,运行结果如下,不过由于是截图所以不是动态的,实际效果是每个条形都会变化长度!好了,这部分就介绍到这,下一篇告诉大家怎么在ui文件中设置控件显示图表!
在这里插入图片描述

  • 作者:lee_swift13
  • 原文链接:https://blog.csdn.net/weixin_43350361/article/details/105376452
    更新时间:2022-08-27 13:59:48