2017-05-04 90 views
1

我想用matplotlib動畫在PyQT GUI上顯示傳感器數據。 我已經有一個工作曲線圖,獲取更新我每次收到新的傳感器值從外部源與此代碼時間:動態更新matplotlib中的多個軸

def __init__(self): 
      self.fig = Figure(figsize=(width, height), dpi=dpi) 
      self.axes = self.fig.add_subplot(111) 
      self.axes.grid() 
      self.xdata = [] 
      self.ydata = [] 
      self.entry_limit = 50 
      self.line, = self.axes.plot([0], [0], 'r') 

    def update_figure_with_new_value(self, xval: float, yval: float): 
      self.xdata.append(xval) 
      self.ydata.append(yval) 

      if len(self.xdata) > self.entry_limit: 
       self.xdata.pop(0) 
       self.ydata.pop(0) 

      self.line.set_data(self.xdata, self.ydata) 
      self.axes.relim() 
      self.axes.autoscale_view() 
      self.fig.canvas.draw() 
      self.fig.canvas.flush_events() 

我現在要擴展的情節,顯示具有相同x軸的另一數據系列。我試圖有以下補充上述初始化代碼來實現這一點:

  self.axes2 = self.axes.twinx() 
      self.y2data = [] 
      self.line2, = self.axes2.plot([0], [0], 'b') 

並在update_figure_with_new_value()函數(用於測試目的我只是試圖1添加到利用yval,我會延伸的所述PARAMS後來功能):

  self.y2data.append(yval+1) 
      if len(self.y2data) > self.entry_limit: 
       self.y2data.pop(0) 
      self.line2.set_data(self.xdata, self.ydata) 
      self.axes2.relim() 
      self.axes2.autoscale_view() 

而不是得到的情節兩條線應該有相同的運動,但只是一個我得到的垂直線爲第二個圖線(藍色),但轉移。第一個軸(紅色)保持不變並且沒問題。

second axis of plot (blue) is wrong

如何使用matplotlib更新多軸讓他們顯示正確的價值觀?

我使用python 3.4.0和matplotlib 2.0.0。

回答

1

由於沒有可用的最小示例,很難說出這種不良行爲的原因。原則上ax.relim()ax.autoscale_view()應該做你需要的。

因此,這裏是工作正常,正在與Python 2.7運行時更新兩臺秤,matplotlib 2.0和PyQt4的一個完整的例子:

import numpy as np 
import matplotlib.pyplot as plt 
from PyQt4 import QtGui, QtCore 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas 
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar 

class Window(QtGui.QMainWindow): 
    def __init__(self): 
     QtGui.QMainWindow.__init__(self) 
     self.widget = QtGui.QWidget() 
     self.setCentralWidget(self.widget) 
     self.widget.setLayout(QtGui.QVBoxLayout()) 
     self.widget.layout().setContentsMargins(0,0,0,0) 
     self.widget.layout().setSpacing(0) 

     self.fig = Figure(figsize=(5,4), dpi=100) 
     self.axes = self.fig.add_subplot(111) 
     self.axes.grid() 
     self.xdata = [0] 
     self.ydata = [0] 
     self.entry_limit = 50 
     self.line, = self.axes.plot([], [], 'r', lw=3) 

     self.axes2 = self.axes.twinx() 
     self.y2data = [0] 
     self.line2, = self.axes2.plot([], [], 'b') 

     self.canvas = FigureCanvas(self.fig) 
     self.canvas.draw() 

     self.nav = NavigationToolbar(self.canvas, self.widget) 
     self.widget.layout().addWidget(self.nav) 
     self.widget.layout().addWidget(self.canvas) 

     self.show() 

     self.ctimer = QtCore.QTimer() 
     self.ctimer.timeout.connect(self.update) 
     self.ctimer.start(150) 


    def update(self): 
     y = np.random.rand(1) 
     self.update_figure_with_new_value(self.xdata[-1]+1,y) 

    def update_figure_with_new_value(self, xval,yval): 
     self.xdata.append(xval) 
     self.ydata.append(yval) 

     if len(self.xdata) > self.entry_limit: 
      self.xdata.pop(0) 
      self.ydata.pop(0) 
      self.y2data.pop(0) 

     self.line.set_data(self.xdata, self.ydata) 
     self.axes.relim() 
     self.axes.autoscale_view() 

     self.y2data.append(yval+np.random.rand(1)*0.17) 

     self.line2.set_data(self.xdata, self.y2data) 
     self.axes2.relim() 
     self.axes2.autoscale_view() 

     self.fig.canvas.draw() 
     self.fig.canvas.flush_events() 


if __name__ == "__main__": 
    qapp = QtGui.QApplication([]) 
    a = Window() 
    exit(qapp.exec_()) 

你可能想測試一下,並彙報是否可以正常工作或不。

+0

我把所有的東西放在和你的例子相同的順序,現在它工作正常。之後,我嘗試撤消行動以獲得更多關於造成此行爲的信息,但現在我無法再重現這一點。感謝您的代碼示例。 –

+0

是的,這就是[mcve]的全部重點。通過創建一個你經常已經解決的問題,如果沒有,這使得找到問題更加容易。下次你可能會記住這一點。 ;-) – ImportanceOfBeingErnest