Skip to main content
 首页 » 编程设计

python之使用 python 和 matplotlib 同时获取数据和更新图形

2025年05月04日11qlqwjy

我正在用 Python 编写代码以通过串行端口与超声波测距仪通信,以执行以下操作:
- 每0.1秒,向传感器发送一个命令进行距离测量,并记录传感器的响应
- 显示最近 5 秒内所有距离测量值的图表

这是我的代码:

import serial 
import numpy as np 
import time 
from matplotlib import pyplot as plt 
 
tagnr=2#Tag number of the sensor that we're pinging   
samplingRate=.1#Sampling Rate in seconds   
graphbuf=50.#Buffer length in samples of logger graph   
 
!#Initialize logger graph   
gdists=np.zeros(graphbuf)   
ax1=plt.axes()   
 
!#Main loop   
nsr=time.time()#Next sample request   
try:   
    while True:   
        statreq(tagnr)#Send status request to sensor over serial port   
        temp,dist=statread(tagnr)#Read reply from sensor over serial port   
        gdists=np.concatenate((gdists[1:],np.array([dist])))   
        print gdists   
        nsr=nsr+samplingRate   
        while time.time()<nsr:   
            pass   
 
finally:   
    ser.close()#Close serial port   
    print 'Serial port closed.'   

现在,我的代码可以获取最后 50 个测量值的数组,但我不知道如何同时在图表中显示这些(我通常使用 Matplotlib 绘制图表)。我应该使用线程吗?或者使用 pyGTK 或 pyQt4 使用动画图形?我也在考虑使用pygame?我的计时机制也不是很理想,但我认为它非常准确。

请您参考如下方法:

matplotlib 具有动画图,允许在显示图时更新数据:take a look at this page .

您的代码可能如下所示:

import serial 
import numpy as np 
import time 
from matplotlib import pyplot as plt 
 
plt.ion() # set plot to animated 
 
tagnr=2#Tag number of the sensor that we're pinging   
samplingRate=.1#Sampling Rate in seconds   
graphbuf=50.#Buffer length in samples of logger graph   
 
!#Initialize logger graph   
gdists=np.zeros(graphbuf)   
ax1=plt.axes()   
 
# make plot 
line, = plt.plot(gdists) 
 
!#Main loop   
nsr=time.time()#Next sample request   
try:   
    while True:   
        statreq(tagnr)#Send status request to sensor over serial port   
        temp,dist=statread(tagnr)#Read reply from sensor over serial port   
        gdists=np.concatenate((gdists[1:],np.array([dist])))   
        print gdists 
 
        line.set_ydata(gdists)  # update the data 
        plt.draw() # update the plot 
 
        nsr=nsr+samplingRate   
        while time.time()<nsr:   
            pass   
 
finally:   
    ser.close()#Close serial port   
    print 'Serial port closed.'   

只是一些建议(可能是坏的):我个人会以释放一些处理器而不损失准确性的方式使用 time.sleep。我还会在您的 try/except block 上放置一些错误类型。而且我认为 np.roll 比 concatenate 更好/更快。