【发布时间】:2019-06-30 15:16:51
【问题描述】:
我在 python 3.7 上。我正在尝试从串行端口读取数据,它将是 7 个不同的字节。然后我想在不同的子图上绘制每个不同的字节。我想每 500 毫秒读取一次串行端口,每次读取时都将新数据添加到子图中。每次读取都会在每个子图上绘制更多数据。这基本上是传感器读数。
这是我写的代码:
从时间导入睡眠 导入序列号 将 matplotlib.pyplot 导入为 plt
f=plt.figure(1)
ax=[0 for x in range(7)]
for i in range(0,7):
ax[i]=f.add_subplot(4,2,1+i)
ser = serial.Serial('COM3', 115200) # Establish the connection on a specific port
counter = 0
byte=ser.readline() #first line not to be plotted
while True:
counter +=1
ser.write(b'9') # send a command to the arduino
byte=ser.read(7) #read 7 bytes back
for i in range(0,7):
ax[i].plot(counter, byte[i]) # Trying to plot the new values to each different subplots
plt.pause(0.01)
sleep(.5) # Delay for one half of a second
该图正在显示,x 轴和 y 轴正在适应我想要 plt 的值,但图上根本没有数据。如果我使用 scatter 而不是 plot 它可以工作,但是它的通用性较差,我无法绘制我想要的图形类型。 我也尝试在不使用串行数据的情况下重现该问题,而只是像这样一个接一个地显示列表的点:
import matplotlib.pyplot as plt
from time import sleep
f=plt.figure()
series=[[4,3,2,1],[8,7,6,5],[12,11,10,9]]
counter=0
ax=[0 for x in range(7)]
for i in range(0,3):
ax[i]=f.add_subplot(4,2,1+i)
for j in range (0,4):
counter=counter+1
for i in range(0,3):
ax[i].plot(counter,series[i][j])
plt.pause(0.01)
sleep(1)
它在做同样的事情,我在图表上的最终图像是: 哪个显示轴采用了我想要绘制的内容,但没有绘制任何内容。 关键是我不想清除整个绘图并重绘所有内容,因为对于数据传感器,我将有大约 30 天的数据连续显示。 我写的代码有什么问题?
编辑: 在 ImportanceOfBeingErnest 发表评论后,我尝试实施给出的答案here。那么代码是:
from time import sleep
import serial
import matplotlib.pyplot as plt
import numpy
plt.ion()
f=plt.figure()
ax=[0 for x in range(7)]
lines=[0 for x in range(7)]
for i in range(0,7):
ax[i]=f.add_subplot(4,2,1+i)
lines[i]=ax[0].plot([],[])
def update_line(hl, new_datax, new_datay):
hl.set_xdata(numpy.append(hl.get_xdata(), new_datax))
hl.set_ydata(numpy.append(hl.get_ydata(), new_datay))
plt.draw()
ser = serial.Serial('COM3', 115200) # Establish the connection on a specific port
counter = 0
byte=ser.readline() #first line not to be plotted
while True:
counter +=1
ser.write(b'9') # send a command to the arduino
byte=ser.read(7) #read 7 bytes back
for i in range(0,7):
update_line(lines[i][0], counter, byte[i]) # Trying to plot the new values to each different subplots
plt.pause(0.01)
sleep(.5) # Delay for one half of a second
但它仍然没有显示任何内容。我有点猜想我错过了一个情节和/或在某处清除,但在尝试了几个选项后无法让它发挥作用。
【问题讨论】:
-
你绘制一个单点的线图。但是在一个点和它自己之间不能建立一条线,而是线需要至少两个点才能成为一条线。当然,您可以在线条上添加一个标记 (marker="o") 以查看点(这与散点图相同)。但如果你真的想要一条线,你应该画出所有的点。
-
哦,我明白了。有没有办法从之前显示的上一点做一条线?您必须重新绘制所有内容吗?
-
嗯,通常你会用越来越多的点来更新行。参见例如this question 如何做到这一点。
-
我尝试了您链接的问题中给出的示例,但它仍然不会显示任何内容,我可能会错过一个情节,或者在某些时候清楚,但很难知道在情节中放置的位置和内容
-
附注 - 由于绘图可能会花费不可预测的时间,因此使用
multiprocessing模块并在单独的进程中读取数据可能是个好主意。然后,您可以将收集的数据通过管道传输到绘图过程。
标签: python matplotlib plot real-time-data