2014-07-16 129 views
4

我用兩個數組獲取一些數據:一個是時間,一個是數值。當我達到1000點時,我觸發一個信號並繪製這些點(x =時間,y =值)。Python實時繪圖

我需要保持與前面的圖相同的數字,但只有一個合理的數字,以避免放慢過程。例如,我想在圖表上保留10,000點。 matplotlib交互式繪圖工作正常,但我不知道如何抹掉第一點,它會非常快地減慢我的電腦速度。 我看着matplotlib.animation,但它似乎只重複相同的情節,並沒有真正實現它。

我真的很想找一個輕量級的解決方案,以避免任何放緩。因爲我獲得了很長時間,所以我擦除了每個循環的輸入數據(第1001個點存儲在第1行等等)。

這裏是我現在,但它一直在圖形上的所有點:

import matplotlib.pyplot as plt 

def init_plot(): 
    plt.ion() 
    plt.figure() 
    plt.title("Test d\'acqusition", fontsize=20) 
    plt.xlabel("Temps(s)", fontsize=20) 
    plt.ylabel("Tension (V)", fontsize=20) 
    plt.grid(True) 

def continuous_plot(x, fx, x2, fx2): 
    plt.plot(x, fx, 'bo', markersize=1) 
    plt.plot(x2, fx2, 'ro', markersize=1) 
    plt.draw() 

我一次調用init功能,並且continous_plot是一個過程,稱爲每次我有1000時間點在我的陣列中。

+0

你有什麼企圖這個自己編程?如果是這樣,請分享您的代碼。 – Ffisegydd

回答

6

您可能擁有的最輕的解決方案是替換現有繪圖的X和Y值。 (或y值只有,如果X的數據不改變一個簡單的例子:

import matplotlib.pyplot as plt 
import numpy as np 
import time 

fig = plt.figure() 
ax = fig.add_subplot(111) 

# some X and Y data 
x = np.arange(10000) 
y = np.random.randn(10000) 

li, = ax.plot(x, y) 

# draw and show it 
ax.relim() 
ax.autoscale_view(True,True,True) 
fig.canvas.draw() 
plt.show(block=False) 

# loop to update the data 
while True: 
    try: 
     y[:-10] = y[10:] 
     y[-10:] = np.random.randn(10) 

     # set the new data 
     li.set_ydata(y) 

     fig.canvas.draw() 

     time.sleep(0.01) 
    except KeyboardInterrupt: 
     break 

該溶液相當快的,以及上面的代碼的最大速度是每秒100個重繪(由限制。在time.sleep),我得到70-80左右,這意味着一個重繪大約需要4毫秒,但情況因人而異取決於後端等

+1

您的解決方案看起來不錯,但使用您的代碼時,軸會被阻擋,繪圖會出現在可見域之外。我可以添加什麼來自動調節軸? 編輯:找到解決方案:我需要在fig.canvas.draw之前添加這兩行: ax.relim() ax.autoscale_view(True,True,True) – CoMartel

5

使用固定大小的數組和情節,使用matplot。

import collections 
array = collections.deque([None] * 1000, maxlen=1000) 

當您追加到數組時,它將刪除第一個元素。

0

我知道我很遲纔回答這個問題,對於您的問題,您可以查看「遊戲杆」包。它基於line.set_data()和canvas.draw()方法,可選軸重新縮放。它還允許交互式文本記錄或圖形繪製(除了圖形繪製)。 沒有必要在一個單獨的線程中做自己的循環,軟件包會照顧它,只是給你想要的更新頻率。另外控制檯仍可用於其他監控命令。 見http://www.github.com/ceyzeriat/joystick/https://pypi.python.org/pypi/joystick(PIP使用操縱桿安裝安裝)

嘗試:

import joystick as jk 
import numpy as np 
import time 

class test(jk.Joystick): 
    # initialize the infinite loop decorator 
    _infinite_loop = jk.deco_infinite_loop() 

    def _init(self, *args, **kwargs): 
     """ 
     Function called at initialization, see the doc 
     """ 
     self._t0 = time.time() # initialize time 
     self.xdata = np.array([self._t0]) # time x-axis 
     self.ydata = np.array([0.0]) # fake data y-axis 
     # create a graph frame 
     self.mygraph = self.add_frame(jk.Graph(name="test", size=(500, 500), pos=(50, 50), fmt="go-", xnpts=10000, xnptsmax=10000, xylim=(None, None, 0, 1))) 

    @_infinite_loop(wait_time=0.2) 
    def _generate_data(self): # function looped every 0.2 second to read or produce data 
     """ 
     Loop starting with the simulation start, getting data and 
    pushing it to the graph every 0.2 seconds 
     """ 
     # concatenate data on the time x-axis 
     self.xdata = jk.core.add_datapoint(self.xdata, time.time(), xnptsmax=self.mygraph.xnptsmax) 
     # concatenate data on the fake data y-axis 
     self.ydata = jk.core.add_datapoint(self.ydata, np.random.random(), xnptsmax=self.mygraph.xnptsmax) 
     self.mygraph.set_xydata(t, self.ydata) 

t = test() 
t.start() 
t.stop()