使用 MatplotlibAnimation 进行 Arduino Live Serial Plotting 变慢
Posted
技术标签:
【中文标题】使用 MatplotlibAnimation 进行 Arduino Live Serial Plotting 变慢【英文标题】:Arduino Live Serial Plotting with a MatplotlibAnimation gets slow 【发布时间】:2017-05-04 08:07:51 【问题描述】:我正在制作一个实时绘图仪来显示来自 Arduino 传感器的模拟变化。 Arduino 向串口打印一个波特率为 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 分钟。 IE。用新值更新图表需要 1 分钟。我也尝试过使用 PyQtGraph,但这从一开始就被延迟了。
除了超过 20 分钟的延迟之外,我在情节中遇到了一些过冲和下冲。
有什么帮助吗?
【问题讨论】:
我认为问题在于 xar 和 yar 变量在一段时间后变得巨大。您可以尝试使用列表推导并改为执行列表的动态读取。 20 分钟后,您最好停止绘图,因为超过 1000 万个连接点的绘图将变得完全不可读。 @Jalo 谢谢。我看到变量太大了。问题是我需要再次重新绘制所有值,因为我每次都在清除绘图以免使其内存过载。我会降低采样频率:-) 您尝试管理的数据太多,无法在每次迭代时动态绘制所有历史数据。对于更简单的方法,我会将每次迭代时接收到的数据存储在一个文件中以供进一步分析,同时仅绘制最后 N 次迭代。 【参考方案1】:如 cmets 中所述,您做错了两件事:
您不断将传入的数据附加到您的数组中,一段时间后这些数据会变得很大 您清除轴并在每次迭代时创建一个新的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 包含使代码正常运行所需的所有元素。
【讨论】:
【参考方案2】:正如 cmets 所提到的,由于它们的大小,从数组中读取自然会变慢。波特率为 9600 时,我在 xar 和 yar 变量中每秒获得大约 130 个串行读数和时间戳; 20 分钟后得到 156000 的大小。将波特率降低到 2400 会将变量的长度降低到 36000,并且可以很容易地重新绘制。
【讨论】:
以上是关于使用 MatplotlibAnimation 进行 Arduino Live Serial Plotting 变慢的主要内容,如果未能解决你的问题,请参考以下文章
Matplotlib animation.FuncAnimation() 动画错过第一帧?
matplotlib animation.save 不生成视频