我正在制作一个实时绘图仪,以显示Arduino传感器的模拟变化。 Arduino以Baudrate 9600为序列打印一个值.Python代码如下所示:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import time
ser = serial.Serial("com3", 9600)
ser.readline()
optimal_frequency = 100
fig = plt.figure(figsize=(6, 6))
ax1 = fig.add_subplot(1, 1, 1)
# the following arrays must be initialized outside the loop
xar = []
yar = []
print(time.ctime())
def animate(i):
global b, xar, yar # otherwise a
for i in range(optimal_frequency):
a = str(ser.readline(), 'utf-8')
try:
b = float(a)
except ValueError:
ser.readline()
xar.append(str(time.time()))
yar.append(b)
ax1.clear()
ax1.plot(xar, yar)
ani = animation.FuncAnimation(fig, animate, interval=optimal_frequency)
plt.show()
在情节中获得正确的响应时间,但是当我绘制超过20分钟时,反应时间增加到约1分钟。即图表需要1分钟才能更新新值。我也试过PyQtGraph但是从一开始就推迟了。
除了超过20分钟的延迟时间外,我在剧情中遇到了一些过冲和下冲。
任何帮助?
答案 0 :(得分:1)
如评论中所述,你做错了两件事:
ax.plot()
。你要做的是:
在初始化函数中,创建一个空的Line2D对象
def init():
line, = ax.plot([], [], lw=2)
return line,
然后在您的更新功能(animate()
)中,您使用line.set_data()
更新积分的坐标。但是,为了保持性能,您必须将数组的大小保持在合理的大小,因此您必须在新数据出现时删除旧数据
def animate(i):
(...)
xar.append(str(time.time()))
yar.append(b)
line.set_data(xar, yar)
return line,
查看一些教程like this one。关于SO的问题也很多,已经回答了你的问题。例如,this answer包含使代码正常工作所需的所有元素。
答案 1 :(得分:0)
正如评论所指出的那样,从阵列中读取因其大小而自然变慢。波特率为9600时,我在 xar 和 yar 变量中获得大约130个串行读数和每秒时间戳;在20分钟后得到156000的大小。将波特率降低到2400会将变量的长度减少到36000,并且可以很容易地重新绘制。