2012-03-18 71 views
3

我想在測量結果爲 運行時執行測量並繪製圖形。這個測量需要一段時間的python(它必須通過慢速連接檢索數據)。問題是測量時圖形凍結。測量 包括設置中心波長,然後測量一些信號。在matplotlib中進行實時繪圖,同時執行需要時間的測量

我的計劃看起來是這樣的:

# this is just some arbitrary library that has the functions set_wavelength and 
# perform_measurement 
from measurement_module import set_wavelength, perform_measurement 
from pylab import * 

xdata = np.linspace(600,1000,30) # this will be the x axis 
ydata = np.zeros(len(xdata)) # this will be the y data. It will 
for i in range(len(xdata)): 
    # this call takes approx 1 s 
    set_wavelength(xdata[i]) 
    # this takes approx 10 s 
    ydata[i] = perform_measurement(xdata) 
    # now I would like to plot the measured data 
    plot(xdata,ydata) 
    draw() 

,當它在IPython中運行與-pylab模塊接通, 但測量運行時這一數字將凍結這將工作。如何修改 的行爲在測量時有交互式繪圖?

你不能簡單地使用pylab.ion(),因爲python在執行測量時很忙。

問候,

德克

回答

0

慢速輸入和輸出是使用線程和隊列在Python的最佳時機。線程有其侷限性,但這種情況下,他們輕鬆有效地工作。

的如何執行此概要:
通常,GUI(例如,matplotlib窗口)需要在主線程,所以做數據集合中的第二線程。在數據線程中,檢查是否有新的數據進入(如果您在某種類型的無限輪詢循環中執行此操作,請稍等片刻以釋放線程)。然後,在需要時,讓主線程知道有一些新數據需要處理/顯示。具體如何做到這一點取決於程序和GUI的細節等。您可以在數據線程中使用一個標誌,您可以從主線程或theading.Event中檢查該標誌,或者,例如,如果您有wx後端用於matplotlib wx.CallAfter很簡單。我建議通過其中一個Python線程教程來了解它,並且使用GUI進行線程通常也有一些問題,所以只需在您的特定後端線程上快速執行一次谷歌即可。這聽起來很麻煩,因爲我簡短地解釋了它,但它非常簡單而且功能強大,並且比從不同進程讀取和寫入同一文件更順暢。

+0

好的,那是我最初的想法,但你會怎麼做?如果繪圖是在一個單獨的線程中,它將無濟於事,因爲程序將在主線程中忙碌。你能舉個例子嗎? – Dirklinux 2012-03-21 12:42:19

+0

我在答案中給出了更詳細的大綱。在這裏回答你的問題:關於「程序將在主線程中忙碌」,因爲你的數據收集是硬件有限的,你的程序在數據收集線程中並不真正「忙碌」,它主要只是在等待數據。至少在我的經驗中,線程在數據收集程序中運行得很好。 – tom10 2012-03-21 15:40:18

+0

非常感謝!將嘗試它,並讓你張貼。 – Dirklinux 2012-03-22 10:53:40

1

可以,但也許有點尷尬,運行數據收集爲serparate過程。我發現子進程模塊中的Popen非常方便。然後讓該數據收集腳本將其在磁盤上的某處保存,並使用

Popen.poll() 

檢查它是否已完成。

它應該工作。

+0

感謝您的迴應,它幫助!我將編寫一個可以使用Popen與繪圖程序進行通信的測量程序,並使用Popen.communicate()將測量數據發回。這樣我就可以爲不同的程序重寫測量程序,並仍然使用相同的繪圖程序。甚至可能使用套接字,所以我可以在一臺計算機上測量並在另一臺計算機上繪製結果。 – Dirklinux 2012-03-19 18:19:49

1

我建議緩衝大數據塊中的數據,並在緩衝區填滿時進行渲染/重新渲染。如果你希望它是非阻塞的看greenlets。

from gevent.greenlet import Greenlet 
import copy 
def render(buffer): 
    ''' 
    do rendering stuff 
    ''' 
    pass 

buff = '' 
while not_finished: 
    buff = connection.read() 
    g = Greenlet(render, copy.deepcopy(buff)) 
    g.start() 
0

看看TraitsChaco,Enthought的類型系統和繪圖庫。他們提供了一個很好的抽象來解決你遇到的問題。一旦Chaco的任何依賴關係發生變化,它就會自行更新。