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

发布于 2024-10-30 01:16:38 字数 1088 浏览 6 评论 0原文

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

I'm writing a code in Python to communicate to an ultrasonic distance meter over the serial port, to do the following:
-Every 0.1 seconds, send a command to the sensor to make a distance measurement, and register the response of the sensor
-Display a plot of all the distance measurements from the last 5 seconds

Here's my code:

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.'  

Right now, my code can acquire an array of the last 50 measurements, but I don't know how to display these in a graph at the same time (I usually plot my graphs using Matplotlib). Should I use threading? Or use an animated graph using pyGTK or pyQt4? I was also thinking of using pygame? My timing mechanism is not very optimal either but I'm thinking it's pretty accurate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怀中猫帐中妖 2024-11-06 01:16:39

matplotlib 具有动画图,允许在显示图时更新数据: 看看此页面

您的代码可能如下所示:

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.roll 比 concatenate 更好/更快。

matplotlib has animated plots that allow the data to be updated while the plot is displayed: take a look at this page.

Your code might look like this:

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.'  

Just some advice (possibly bad): I would personally use time.sleep in a way that frees up some processor without losing accuracy. I would also put some error type on your try/except block. And I think np.roll is better/faster than concatenate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文