使用 matplotlib 从管道绘制实时数据

当你想要实时显示传入数据时,这可能很有用。例如,该数据可以来自连续采样模拟信号的微控制器。

在这个例子中,我们将从命名管道(也称为 fifo)获取数据。对于此示例,管道中的数据应该是换行符所分隔的数字,但你可以根据自己的喜好进行调整。

示例数据:

100
123.5
1589

有关命名管道的更多信息

我们还将使用标准库集合中的数据类型 deque。deque 对象的工作方式与列表非常相似。但是对于 deque 对象,在将 deque 对象保持为固定长度的同时,很容易向其添加内容。这允许我们将 x 轴保持在固定长度,而不是总是将图形一起增长和压扁。有关双端队列对象的更多信息

选择合适的后端对性能至关重要。检查操作系统上的后端是什么,并选择快速后端。对我来说只有 qt4agg 和默认的后端工作,但默认的一个太慢了。有关 matplotlib 中后端的更多信息

此示例基于绘制随机数据的 matplotlib 示例

此代码中的所有’字符都不是要删除的。

import matplotlib
import collections
#selecting the right backend, change qt4agg to your desired backend
matplotlib.use('qt4agg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation

#command to open the pipe
datapipe = open('path to your pipe','r')

#amount of data to be displayed at once, this is the size of the x axis
#increasing this amount also makes plotting slightly slower
data_amount = 1000

#set the size of the deque object
datalist = collections.deque([0]*data_amount,data_amount)

#configure the graph itself
fig, ax = plt.subplots()
line, = ax.plot([0,]*data_amount)

#size of the y axis is set here
ax.set_ylim(0,256)

def update(data):
        line.set_ydata(data)
        return line,

def data_gen():
    while True:
        """
        We read two data points in at once, to improve speed
        You can read more at once to increase speed
        Or you can read just one at a time for improved animation smoothness
        data from the pipe comes in as a string,
        and is seperated with a newline character,
        which is why we use respectively eval and rstrip.
        """
        datalist.append(eval((datapipe.readline()).rstrip('\n')))
        datalist.append(eval((datapipe.readline()).rstrip('\n')))
        yield datalist

ani = animation.FuncAnimation(fig,update,data_gen,interval=0, blit=True)
plt.show()

如果你的绘图在一段时间后开始延迟,请尝试添加更多的 datalist.append 数据,以便每帧读取更多行。或者,如果可以的话,选择更快的后端。

这适用于我的 1.7ghz i3 4005u 上的 150hz 数据。