首页 > 编程语言 >Python 实时生成曲线的两种方法-Matplotlib/Pyqtgraph

Python 实时生成曲线的两种方法-Matplotlib/Pyqtgraph

时间:2023-04-24 09:55:56浏览次数:65  
标签:set obsX obsY Python self Pyqtgraph Matplotlib import line

前言

Matplotlib 更倾向于制作出版质量的图形,对 matlab 程序员来说更直观。
pyqtgraph 不像 matplotlib 那样完整/成熟,但运行速度要快得多,而且pyqtgraph 旨在用于数据采集和分析应用程序,对于 python/qt 程序员来说更直观。
Matplotlib(据我所知)不包括许多 pyqtgraph 的功能,例如图像交互、体积渲染、参数树、流程图等。

第一种方式 Matplotlib

import threading
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.lines as line
import numpy as np
import random
import time
 
# 定义画布
fig = plt.figure(figsize=(10,6), dpi=80)
ax = plt.subplot(211,ylim=(0,5))
bx = plt.subplot(212,ylim=(0,5))
line = line.Line2D([], [])  # 绘制直线

obsX = []
obsY = []

# 初始化图像
def plot_init():
    ax.add_line(line)
    return line, # 必须加逗号,否则会报错(TypeError: 'Line2D' object is not iterable)
 
# 更新图像(animation会不断调用此函数刷新图像,实现动态图的效果)
def plot_update(i):
    global obsX
    global obsY

    if len(obsX) < 100:
        ax.set_xlim(min(obsX),max(obsX)+30)  # 横坐标范围(横坐标的范围和刻度可根据数据长度更新)
    else:
        ax.set_xlim(obsX[-80],max(obsX) * 1.2)  # 横坐标范围(横坐标的范围和刻度可根据数据长度更新)
    
    ax.set_ylim(min(obsY), max(obsY)+10)  # 纵坐标范围(横坐标的范围和刻度可根据数据长度更新)
    ax.set_title("CPU Loading",fontsize=8)  # 设置title

    bx.set_ylim(min(obsY), max(obsY)+10)  # 纵坐标范围(横坐标的范围和刻度可根据数据长度更新)
    bx.set_title("Memory Loading",fontsize=8)  # 设置title

    line.set_xdata(np.array(obsX))  # 更新直线的数据
    line.set_ydata(np.array(obsY))  # 更新直线的数据
	# 大标题(若有多个子图,可为其设置大标题)
    plt.suptitle('System Loading',fontsize=8)
    # 重新渲染子图
    ax.figure.canvas.draw()  # 必须加入这一行代码,才能更新title和坐标!!!
    return line,  # 必须加逗号,否则会报错(TypeError: 'Line2D' object is not iterable)
 
# 绘制动态图
ani = animation.FuncAnimation(fig,   # 画布
							  plot_update,  # 图像更新
                              init_func=plot_init,  # 图像初始化
                              frames=1,
                              interval=30,  # 图像更新间隔
                              blit=True)
 
# 数据更新函数
def dataUpdate_thead():
    global obsX
    global obsY
    i = 1
    while True:  # 为了方便测试,让数据不停的更新
        obsX.append(i)
        obsY.append(random.randrange(100, 200))
        i += 1
        time.sleep(1)
 
# 为数据更新函数单独创建一个线程,与图像绘制的线程并发执行
ad_rdy_ev = threading.Event()
ad_rdy_ev.set()  # 设置线程运行
t = threading.Thread(target=dataUpdate_thead, args=()) # 更新数据,参数说明:target是线程需要执行的函数,args是传递给函数的参数)
t.daemon = True
t.start()  # 线程执行
 
plt.show() # 显示图像

image

第二种方式 Pyqtgraph

import sys
import time
import datetime
import numpy as np
import pyqtgraph as pg
import random
from pyqtgraph.Qt import QtCore, QtWidgets

class TimeAxisItem(pg.AxisItem):
    """Internal timestamp for x-axis"""
    def __init__(self, *args, **kwargs):
        super(TimeAxisItem, self).__init__(*args, **kwargs)

    def tickStrings(self, values, scale, spacing):
        """Function overloading the weak default version to provide timestamp"""

        return [QtCore.QTime().currentTime().addMSecs(value).toString('hh:mm:ss') for value in values]

class App(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        #### Create Gui Elements ###########
        self.mainbox = QtWidgets.QWidget()
        self.setCentralWidget(self.mainbox)
        self.mainbox.setLayout(QtWidgets.QVBoxLayout())

        self.canvas = pg.GraphicsLayoutWidget(show=True, size=(600,300))
        self.mainbox.layout().addWidget(self.canvas)

        self.label = QtWidgets.QLabel()
        self.mainbox.layout().addWidget(self.label)

        #  line plot
        self.cpuplot = self.canvas.addPlot(title="CPU Loading", axisItems={'bottom': TimeAxisItem(orientation='bottom')})
        self.p1 = self.cpuplot.plot(pen='y')

        self.canvas.nextRow()

        self.memplot = self.canvas.addPlot(title="Memory Loading", axisItems={'bottom': TimeAxisItem(orientation='bottom')})
        self.p2 = self.memplot.plot(pen='r')

        #### Set Data  #####################
        self.X = []
        self.Y = []

        self.counter = 0
        self.fps = 0.
        self.lastupdate = time.time()

        #### Start  #####################
        self._update()

    def _update(self):
        
        self.X.append(datetime.datetime.now().strftime('%H:%M:%S').replace(':','.'))
        self.Y.append(random.randrange(100, 200))

        self.xdata = np.array(self.X)
        self.ydata = np.array(self.Y)
        
        # self.img.setImage(self.data)
        self.p1.setData(self.ydata)
        self.p2.setData(self.ydata)

        now = time.time()
        dt = (now-self.lastupdate)
        if dt <= 0:
            dt = 0.000000000001
        fps2 = 1.0 / dt
        self.lastupdate = now
        self.fps = self.fps * 0.9 + fps2 * 0.1
        tx = 'Mean Frame Rate:  {fps:.3f} FPS'.format(fps=self.fps )
        self.label.setText(tx)
        QtCore.QTimer.singleShot(1, self._update)
        self.counter += 1
        # time.sleep(1)


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    thisapp = App()
    thisapp.setWindowTitle(u'System Loading')
    thisapp.show()    
    sys.exit(app.exec())

image

标签:set,obsX,obsY,Python,self,Pyqtgraph,Matplotlib,import,line
From: https://www.cnblogs.com/cokefentas/p/17348522.html

相关文章

  • Python环境安装与配置
    Python进行安装:https://www.python.org/如下是针对Windows的下载方式 下载后进行安装,选择自己的安装路径环境配置:script的目录和Python目录添加到path里面 输入python-V 安装配置成功......
  • [oeasy]python0137_相加运算_python之禅_import_this_显式转化
    变量类型相加运算回忆上次内容上次讲了是从键盘输入变量input函数可以有提示字符串需要有具体的变量接收输入的字符串 输入单个变量没有问题但是输入两个变量之后一相加就非常离谱 ​ 添加图片注释,不超过140字(可选)......
  • python发邮件|4-20
    SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。首先,我们来构造一个最简单的纯文本邮件:fromemail.mime.textimportMIMETextmsg=MIMEText('hello......
  • python老男孩第一课
    python 解释器  Cpython 官方标准   --Ipython  --Jython  --PYPY 编程风格   ---缩进统一   -----变量  一般规定(常量大写的  变量  小写的)  ID(变量名)  看变量指向的内存ID   标识符的第一个字符必须是字母表中......
  • python中的字符串和列表
    name="1"name='1'name="""1"""""name='''1'''#都为正确的字符串定义方式#字符串中一个字符占一个空间 #字符串切片格式为[起始:结束:步长]#从起始开始,到结束前一位结束不含结束本身,,默认步长为1,步长可为正可为负a[-4:]#取出a字符串的最后四位#如果只有一......
  • python与c/java的异
    1.注释#为单行注释"""这里是多行注释"""‘’‘这个也可以是多行注释’‘’2.赋值在python中赋值不需要特定变量的类型,并且可以一个等号用于多个赋值,例如name,age,sex="slack",20,"man" 3.输入#输入为函数input()#例1:a=input("请输入内容")#注意in......
  • 【Python】实现按位右移补零操作(同java中的>>>操作)
    答案#Python代码,模拟Java中int型的数的按位右移补零操作defright_shift(val,n):return(val%0x100000000)>>n  逐步推导和解释推论一:对于一个32位的(int型的)二进制,Python中的>>操作等同于Java种的>>>操作证明如下:Python中:binary_value>>n是该二......
  • python结合pandas把excel列转行
    需求,在实际工作中,需要对比两个表格的数据,但是A表格的行和B表格的列做对比,但是由于环境的限制,不能用sql去进行列转行操作,就利用pandas进行一个简单的列转行(没有复合表头)。这种没有多个sheet情况,多个sheet的情况需要切换到需要的sheet内。首先下载pandas,pipinstallpandas 然后......
  • Leetcode 88. 合并两个有序数组 Python题解
    来源:力扣(LeetCode)链接:https://leetcode.cn/problems/merge-sorted-array著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。1.暴力法解题思路:由于题目要求原地合并,直接返回nums1数组。因此一个可行的方案是合并两个列表,然后对合并后的列表进行排序。用......
  • python解释器中ctrl+D和ctrl+Z有什么不同
    在Python解释器中,`Ctrl+D`和`Ctrl+Z`都可以用于退出解释器,但是它们的行为略有不同。`Ctrl+D`在Unix/Linux系统中被称为EOF(EndOfFile),表示输入结束。在Python解释器中,当输入`Ctrl+D`时,解释器会将当前输入的内容作为一个完整的语句执行,并退出解释器。`Ctrl+Z`在Wi......