2015-08-25 151 views
1

我試圖在matplotlib中獲得實時頻譜分析器類型陰謀。我有一些代碼工作(與在計算器上其他職位幫助)如下:matplotlib中的實時陰謀 - python

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

plt.axis([0, 1000, 0, 1]) 
plt.ion() 
plt.show() 

i=0 
np.zeros([1,500],'float') 
lines=plt.plot(y[0]) 

while 1: 
    i=i+1 
    lines.pop(0).remove() 
    y = np.random.rand(1,100) 
    lines=plt.plot(y[0]) 
    plt.draw() 

代碼工作,我得到我想要的東西,但有一個嚴重的問題。情節窗口會在一段時間後凍結。我知道該程序仍在運行,通過檢查變量(我在Anaconda/Spyder中運行代碼,所以我可以看到變量)。然而,繪圖窗口會顯示「無響應」,如果我通過ctrl + c終止Spyder中的python程序,繪圖窗口會恢復生命並顯示最新的繪圖。

因爲如何進一步調試問題,所以我在這裏不知所措。任何人提供幫助?

感謝

回答

0

要回答我自己,我解決了這個問題由

plt.draw() 

後加入

plt.pause(0.01) 

這可能允許GUI來完成繪圖,有的地方清空緩衝區(我的猜測)在新數據進來之前。

1

我不確定是否加plt.pause將完全解決您的問題。在應用程序崩潰之前可能需要更長的時間。您的應用程序使用的內存似乎隨着時間的推移而不斷增加(即使在添加plt.pause之後)。以下是兩個建議,可以幫助您與您的當前問題:

  1. 而不是刪除/與removeplot每次迭代重建線的藝術家,我會用同樣的藝術家在整個動畫,簡單地更新其ydata

  2. 我會用明確的處理程序斧頭和圖形,並通過調用pyplotshow明確draw圖上managercanvas,而不是與隱電話去,下面的post by tcaswell給出的建議。

按照上面的代碼看起來是這樣的:

import numpy as np 
import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 
ax.axis([0, 100, 0, 1]) 

y = np.random.rand(100) 
lines = ax.plot(y) 

fig.canvas.manager.show() 

i=0 
while 1: 
    i=i+1 
    y = np.random.rand(100) 
    lines[0].set_ydata(y) 
    fig.canvas.draw() 
    fig.canvas.flush_events() 

我已經運行上面的代碼有一個良好的10分鐘,由應用程序所使用的內存保持穩定整個時間,而當前代碼使用的內存(無plt.pause)在同一時期增加了大約30MiB。

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=100, xnptsmax=1000, 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()