使用 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 資料。