如何使用 PyQtGraph 提高速度并使用多个绘图拆分数据?
问题描述
我正在使用 STM32 套件从串口读取数据.问题是我需要使用自己的时间戳来绘制 ADC 数据.这意味着 x 轴应该是我的 RTC 时间(为此使用 ms),y 轴是 ADC 数据.有用于绘图串行端口的程序,但正如我所说,我需要为图形设置自己的时间.我为此尝试了 matplotlib,但它真的很慢.然后使用了pyqtgraph和这个脚本:
I am reading datas from serial port using an STM32 kit. Problem is that I need to use own timestamp for plot ADC datas. That is mean x-axis should be my RTC time(using ms for this) and y-axis is ADC datas. There are programs for plot serial port but as I said I need to set own time for graph. I tried matplotlib for this but it was really slow. Then have used pyqtgraph and this script:
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 这样的图.我的数据与';'分开.
This is slow too but fast compare with mathplotlib. Now I can't find how split my timestamp and ADC datas for plot like x,y. My datas are spliting with ';'.
感谢您的回答.
已
我改变了我的代码阅读速度,寻找足够的知识.但是要知道它正在绘制一些故障,例如时间戳向前跳跃并返回或非常大量的 x 轴数据.我正在串行端口 GUI 上监视数据,但找不到任何错误数据.我认为有些东西来自 Python 代码.我可以忽略这些绘图程序的故障吗?
I changed my code reading speed looking enough for know. But know it is plotting some glitches like timetamp is jumping with forward and come back or very big numbers of x-axis datas. I am monitoring datas on a serial port GUI and I can't find any wrong data. Somethings is coming from Python code, i think. Can I ignore these glitches on plotting program?
现在编码:
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()
时,读取的数据将在末尾包含换行符
(参见 Python 通用换行符,可能是
如果您从 Windows 发送).
When you use Serial.readline()
the data read will contain the newline character
at the end (see Python univeral newlines, could be
if you send from Windows).
首先解码接收到的字节并删除换行符:
First decode the bytes received and remove the newline character:
data_string = r.readline().decode('utf-8').strip()
然后在处拆分字符串:
data_split = data_string.split(':')
现在 data_split
是一个包含条目的列表
Now data_split
is a list with the entries
[packetCount, databuffer, sec, subsec]
您可以将它们转换为浮点数或整数并将它们放入 Numpy 数组中.
and you can convert them to floats or integers and put them in the Numpy array.
速度提升
Serial.readline
可能会减慢您的代码速度.使用类似 https://stackoverflow.com/a/56632812/7919597 的内容.
Serial.readline
might slow down your code. Use something like this https://stackoverflow.com/a/56632812/7919597 .
还可以考虑将数据转移到一个固定的 numpy 数组中,而不是每次都使用 xdata = np.array(data, dtype='float64')
创建一个新数组.
Also consider shifting the data in a fixed numpy array instead of creating a new one each time with xdata = np.array(data, dtype='float64')
.
请参阅 在 numpy 数组中移动元素
我将这些函数与 Thread
结合使用
I am using these functions in combination with a Thread
like
import threading
import queue
q = queue.Queue()
thread = threading.Thread(target=read_from_port, args=(serial_port, q))
thread.start()
从串口读取.
在 PyQtGraph 示例中有一个非常有用的示例:
There is a very helpful example in the PyQtGraph examples:
https://github.com/pyqtgraph/pyqtgraph/blob/develop/examples/scrollingPlots.py
Is 显示了使用 Numpy 数组绘制滚动图的三种不同方法.
Is shows three different methods for plotting scrolling plots with Numpy arrays.
我最终使用了方法 1 和 3 的组合,同时移动了从串行端口读取的尽可能多的位置.
I ended up using a combination of method 1 and 3, shifting as many places as were read from the serial port in the meantime.
相关文章