如何使用 PyQtGraph 提高速度并使用多个绘图拆分数据?
Posted
技术标签:
【中文标题】如何使用 PyQtGraph 提高速度并使用多个绘图拆分数据?【英文标题】:How to increase speed and split data with multiple plots using PyQtGraph? 【发布时间】:2020-04-15 15:20:50 【问题描述】:我正在使用 STM32 套件从串口读取数据。问题是我需要使用自己的时间戳来绘制 ADC 数据。这意味着 x 轴应该是我的 RTC 时间(为此使用 ms),y 轴是 ADC 数据。有用于绘图串行端口的程序,但正如我所说,我需要为图形设置自己的时间。我为此尝试了 matplotlib,但它真的很慢。然后使用了pyqtgraph和这个脚本:
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
import serial
app = QtGui.QApplication([])
p = pg.plot()
p.setWindowTitle('live plot from serial')
curve = p.plot()
data = [0]
raw=serial.Serial("/dev/ttyACM0",115200)
#raw.open()
def update():
global curve, data
line = raw.readline()
data.append(int(line))
xdata = np.array(data, dtype='float64')
curve.setData(xdata)
app.processEvents()
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
这也很慢,但与 mathplotlib 相比很快。现在我找不到如何分割我的时间戳和 ADC 数据来绘制像 x,y 这样的图。我的数据与';'分开。
感谢您的回答。
已编辑:
我改变了我的代码阅读速度,寻找足够的知识。但是要知道它正在绘制一些故障,例如时间戳向前跳跃并返回或非常大量的 x 轴数据。我正在串行端口 GUI 上监视数据,但找不到任何错误数据。我认为有些东西来自 Python 代码。我可以忽略这些绘图程序的故障吗?
现在编码:
import numpy as np
import pyqtgraph as pg
import serial
app = pg.Qt.QtGui.QApplication([])
p = pg.plot()
p.setWindowTitle('live plot from serial')
curve = p.plot()
data = [0]
tdata = [0]
temp = [0]
datax = [0]
datay = [0]
temp = 0
now = 0
k = 0
raw=serial.Serial("/dev/ttyACM0",115200, timeout=None)
while p.isVisible():
line = raw.readline().decode('utf-8').strip()
print("raw line:", line)
line = str(line)
print("str line:", line)
line = line.split(':')
print("splitted line:", line)
if len(line) >= 4:
print("line>4:", line)
tdata = line[0]
data = line[1]
print("line[0]; line[1]:", tdata, line)
tdata = int(tdata)
data = int(data)
print("int(tdata)", tdata)
print("int(line)", data)
datax.append(int(tdata))
datay.append(int(data))
xdata = np.array(datax, dtype='float64')
ydata = np.array(datay, dtype='float64')
p.setXRange(tdata-500, tdata+500, padding=0)
curve.setData(xdata, ydata)
# p.setYRange(0 ,data+30, padding=0)
print("now will refresh the plot")
app.processEvents()
else:
print("line<4:", line)
【问题讨论】:
您能否展示您的数据示例行,以便我们讨论如何拆分它? 'PRINTF("%d:%d:%d:%d\n",data_s.packetCount, databuffer,dat.frame.sec,dat.frame.subsec);'这是我的包 编辑了我的答案。 再次感谢乔。我想再问一件事。例如,如何限制图形仅在屏幕上监视 1000 毫秒。它从 0 开始并继续在同一个屏幕上。对于太多的样本,很难识别数据。 我的情况是,我依赖于具有固定采样率的微控制器。在您的情况下,这可能是 STM32,我使用的是 SAMD21。然后,您可以计算要显示的所需样本数量,并从您的 numpy 数组(可能更大,例如大小的两倍)中分割它们。 【参考方案1】:拆分数据
当您使用 Serial.readline()
时,读取的数据将在末尾包含换行符 \n
(请参阅 Python 通用换行符,如果您从 Windows 发送,则可能是 \r\n\
)。
首先解码接收到的字节并删除换行符:
data_string = r.readline().decode('utf-8').strip()
然后在:
处拆分字符串
data_split = data_string.split(':')
现在data_split
是一个包含条目的列表
[packetCount, databuffer, sec, subsec]
您可以将它们转换为浮点数或整数并将它们放入 Numpy 数组中。
速度提升
Serial.readline
可能会减慢您的代码速度。使用类似https://***.com/a/56632812/7919597 的东西。
还可以考虑将数据转移到一个固定的 numpy 数组中,而不是每次都使用 xdata = np.array(data, dtype='float64')
创建一个新数组。
见Shift elements in a numpy array
我将这些功能与Thread
类似
import threading
import queue
q = queue.Queue()
thread = threading.Thread(target=read_from_port, args=(serial_port, q))
thread.start()
从串口读取。
在 PyQtGraph 示例中有一个非常有用的示例:
https://github.com/pyqtgraph/pyqtgraph/blob/develop/examples/scrollingPlots.py
Is 显示了使用 Numpy 数组绘制滚动图的三种不同方法。
我最终使用了方法 1 和 3 的组合,同时移动了从串行端口读取的尽可能多的位置。
【讨论】:
非常感谢您的帖子似乎很有帮助。我正在尝试作为新手学习 Python,所以我不能很好地理解你的线程示例,但我也会检查一下。以上是关于如何使用 PyQtGraph 提高速度并使用多个绘图拆分数据?的主要内容,如果未能解决你的问题,请参考以下文章