如何使用 PyQtGraph 提高速度并拆分具有多个绘图的数据?



我正在使用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 这样的图。我的数据与";"分开。

感谢您的回答。

编辑:

我改变了我的代码读取速度,看起来足够知道。但是要知道它正在绘制一些故障,例如timetamp正在向前跳跃并返回或大量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)

拆分数据

当您使用Serial.readline()读取的数据将在末尾包含换行符n(请参阅 Python 通用换行符,如果您从 Windows 发送,可能会rn(。

首先解码收到的字节并删除换行符:

data_string = r.readline().decode('utf-8').strip()

然后在:处拆分字符串

data_split = data_string.split(':')

现在data_split是一个包含条目的列表

[packetCount, databuffer, sec, subsec]

您可以将它们转换为浮点数或整数并将它们放入 Numpy 数组中。

速度提升

Serial.readline可能会减慢代码速度。使用类似这样的东西 https://stackoverflow.com/a/56632812/7919597.

还可以考虑在固定的numpy数组中移动数据,而不是每次都使用xdata = np.array(data, dtype='float64')创建一个新数组。

请参阅 numpy 数组中的 Shift 元素

我正在将这些功能与类似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 的组合,同时移动了从串行端口读取的尽可能多的位置。

最新更新