PyQt5在窗口上显示动态图表

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

import sys
import matplotlib
import datetime

matplotlib.use("Qt5Agg")
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication,  QVBoxLayout, QSizePolicy, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt


class MyMplCanvas(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)

    '''启动显示动态图'''
    def Display_dynamic_gantt(self, *args, **kwargs):
        # 设置一个时间对象
        timer = QtCore.QTimer(self)
        # 连接需要动态刷新的方法函数
        timer.timeout.connect(self.update_figure)
        # 表示每1秒钟刷新一次
        timer.start(1000)

    '''绘制动态图方法函数,可以在这里定义自己的绘图逻辑'''
    def update_figure(self):
        # 每次重新绘制前需要清楚之前绘制的内容
        # 获取当前的系统时间
        now = datetime.datetime.now()
        self.axes.clear()
        l1 = now.second * 1.8
        if l1 > 60:
            l1 = 60
        l2 = now.second * 1.5
        if 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()


class MatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)
        self.initUi()

    def initUi(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文件中设置控件显示图表!
在这里插入图片描述

发布了17 篇原创文章 · 获赞 3 · 访问量 1798

猜你喜欢

转载自blog.csdn.net/weixin_43350361/article/details/105376452