2016-04-29 101 views
1

我想用pyqtgraph做一個實時繪圖。我正在使用Pyserial從arduino讀取數據。我在使用pyqtgraph之前嘗試了matplotlib庫,但它沒有給我速度,我需要繪製。因此,尋找另一種繪製實時數據的方式,我遇到了PyQtgraph。我閱讀文檔和大量的例子,我發現這兩個例子:使用PyQtGraph和Pyserial繪製時間

pltting with sample interval

plotting using pyqt4

兩者都繪製成時間的函數,而這正是我需要做的。我修改了其中的每一個以使用Pyserial從Arduino獲取數據。問題在於它仍然非常緩慢。

這是代碼(從第二個鏈接)我使用:

class TimeAxisItem(pg.AxisItem): 
    def __init__(self, *args, **kwargs): 
    super(TimeAxisItem, self).__init__(*args, **kwargs) 

    def tickStrings(self, values, scale, spacing): 
    return [QTime().addMSecs(value).toString('mm:ss') for value in values] 

class MyApplication(QtGui.QApplication): 
    def __init__(self, *args, **kwargs): 
    super(MyApplication, self).__init__(*args, **kwargs) 
    self.t = QTime() 
    self.t.start() 

    self.data = deque(maxlen=20) 

    self.win = pg.GraphicsWindow(title="Basic plotting examples") 
    self.win.resize(1000,600) 

    self.plot = self.win.addPlot(title='Timed data', axisItems={'bottom': TimeAxisItem(orientation='bottom')}) 
    self.curve = self.plot.plot() 

    self.tmr = QTimer() 
    self.tmr.timeout.connect(self.update) 
    self.tmr.start(100) 

    print "Opening port" 
    self.raw=serial.Serial("com4",9600) 
    print "Port is open" 


    def update(self): 
    line = self.raw.read() 
    ardString = map(ord, line) 
    for number in ardString: 
     numb = float(number/77.57) 
     print numb 
     self.data.append({'x': self.t.elapsed(), 'y': numb}) 
     x = [item['x'] for item in self.data] 
     y = [item['y'] for item in self.data] 
     self.curve.setData(x=x, y=y) 

def main(): 
    app = MyApplication(sys.argv) 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

我能做些什麼,隨着時間的推移繪製更快看來,我正在失去與此代碼一些數據?

真的希望你能幫助我。

+1

您可以通過使用[Python Profiler](https://docs.python.org/2/library/profile.html)來調查哪些函數使用最多的執行時間。我真的建議你嘗試一下。 – titusjan

回答

0

在你更新功能,嘗試調用

self.curve.clear() 

在函數的開始。

+0

Thnak你的答案。你的意思是在for循環之後?或之前呢? –

+0

嘗試將它作爲for循環的第一行。然而,看着你的腳本,我不確定這是什麼地方。這一秒我沒有在我面前的Arduino,否則我會嘗試排除故障。你確定你的更新函數在超時之前完成並且試圖重新啓動更新函數嗎? – user2070870

0

讓我感到有些遺憾的是這裏發生的事情的時間,而不是pyqtgraph的細節。你的更新方法是按照你的QTimer對象以100ms的間隔輪詢串口,所以在9600波特率時,你的端口可以產生9600bps * .1sec = 960字節。然而,你的serial.Serial.read()不帶參數默認爲大小= 1元的位置:http://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read

所以看起來好像你是在你的更新調用只讀取1個字節每100ms:

line = self.raw.read() 

所以我的猜測是,你應該把更多的東西明智的讀取大小,1024:

line = self.raw.read(1024) 

與在serial.Serial實例指定超時時間:

self.raw=serial.Serial("com4",9600,timeout=0) 

這樣,讀取不會阻塞,只是返回緩衝區中可用的全部數據量。