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

时间:2011-03-31 20:23:04

标签: python multithreading matplotlib ipython

我正在用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?我的计时机制也不是很优,但我认为它非常准确。

1 个答案:

答案 0 :(得分:1)

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块上添加一些错误类型。我认为np.rollconcatenate更好/更快。