在matplotlib

时间:2017-05-04 14:25:11

标签: python matplotlib

我想在带有matplotlib动画的PyQT GUI上显示传感器数据。 我已经有了一个工作Plot,每当我从外部源接收到具有以下代码的新传感器值时,它就会获得更新:

    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轴的另一个数据系列。我尝试使用上面的init-code添加以下内容来实现此目的:

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

并且在update_figure_with_new_value()函数中(出于测试目的,我只是尝试向yval添加1,我将在稍后扩展函数的参数):

            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 个答案:

答案 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_())

您可能需要对此进行测试并报告其是否正常工作。