简体   繁体   中英

PyQt4 matplotlib does not plot my real time data

I am new to PyQt4 and real time plots. I am trying to plot some random real time data on PyQt4 application using matplotlib and Python2.7 . My code looks like this:

#!/usr/bin/env python

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import random
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
import time


class mplCanvas(FigureCanvas):

    def __init__(self, parent=None):
        self.fig = plt.figure(1)
        self.ax = self.fig.add_subplot(111)
        self.ax.grid(True)
        self.manager = plt.get_current_fig_manager()
        super(mplCanvas, self).__init__(self.fig)
        self.setParent(parent)
        self.init_figure()


class CustomFigCanvas(mplCanvas):

    def __init__(self, *args, **kwargs):
        mplCanvas.__init__(self, *args, **kwargs)

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.updateFigure)

    def init_figure(self):

        xaxis = np.arange(0, 100, 1)
        yaxis = np.array([0]*100)
        self.ax.set_title("Realtime Waveform Plot")
        self.ax.set_xlabel("Time")
        self.ax.set_ylabel("Amplitude")
        self.ax.axis([0, 100, -1.5, 1.5])
        self.line1 = self.ax.plot(xaxis, yaxis, '-')
        self.values = []


    def addData(self):

        self.values.append(random.random() * 2 - 1)

    def updateFigure(self):

        self.addData()
        CurrentXAxis=np.arange(len(self.values)-100, len(self.values), 1)
        self.line1[0].set_data(CurrentXAxis, np.array(self.values[-100:]))
        self.ax.axis([CurrentXAxis.min(), CurrentXAxis.max(), -1.5, 1.5])
        self.manager.canvas.draw()

And in the main application I call graph = CustomFigCanvas() But all it does is it prints the plot with a straight line at 0 and the graph does not update at all. I cannot figure out what am I doing wrong. Why my plot is not updating? I was trying several options and still have the same result. I tried to do QThread to emit samples of data but it still did not work. All I get is a straight line. Do you have any suggestions? Any tips would be much appreciated. Thank you.

The main problem is that you set up a QTimer but never start it. So the updating function will never be called. What you need to do is something like

self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.updateFigure)
self.timer.start(1000) # 1000 milliseconds

Another problem is then how you create the data to update. The way it is in the code produces arrays of different length for the x and y coordinates, leading to errors.

Here is a complete running example where I also got rid of the unnecessary double subclassing.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import random
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys


class CustomFigCanvas(FigureCanvas):

    def __init__(self, parent=None, *args, **kwargs):
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)
        self.ax.grid(True)
        super(CustomFigCanvas, self).__init__(self.fig)
        self.setParent(parent)
        self.init_figure()

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.updateFigure)
        self.timer.start(1000)

    def init_figure(self):

        xaxis = np.arange(0, 100, 1)
        yaxis = np.array([0]*100)
        self.ax.set_title("Realtime Waveform Plot")
        self.ax.set_xlabel("Time")
        self.ax.set_ylabel("Amplitude")
        self.ax.axis([0, 100, -1.5, 1.5])
        self.line1 = self.ax.plot(xaxis, yaxis, '-')
        self.values = []
        self.fig.tight_layout()

    def addData(self):
        self.values.append(random.random() * 2 - 1)

    def updateFigure(self):
        self.addData()
        CurrentXAxis=np.arange(len(self.values))
        self.line1[0].set_data(CurrentXAxis, np.array(self.values))
        self.ax.axis([CurrentXAxis.min()-0.001, CurrentXAxis.max()+0.001, -1.5, 1.5])
        self.fig.canvas.draw()

class App(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)   
        self.tab = QtGui.QWidget()
        self.setCentralWidget(self.tab)
        self.tablayout = QtGui.QVBoxLayout(self.tab)
        self.canvas = CustomFigCanvas()
        self.tablayout.addWidget(self.canvas)

app = QtGui.QApplication(sys.argv)
thisapp = App()
thisapp.show()
app.exec_()

In your code you had the following errors:

  • You never started the timer, you should use: {your timer}.start({period in ms})
  • Arrays have different sizes.
  • Change self.manager.canvas.draw() to self.draw()
  • init_figure was never declared in mplCanvas

import sys
from PyQt4 import QtGui

import numpy as np
import matplotlib
matplotlib.use("Qt4Agg")
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import random
from PyQt4 import QtCore


class mplCanvas(FigureCanvas):
    def __init__(self, parent=None):
        self.fig = plt.figure(1)
        self.ax = self.fig.add_subplot(111)
        self.ax.grid(True)
        super(mplCanvas, self).__init__(figure=self.fig)
        self.setParent(parent)
        self.init_figure()

    def init_figure(self):
        pass


class CustomFigCanvas(mplCanvas):
    def __init__(self, *args, **kwargs):
        mplCanvas.__init__(self, *args, **kwargs)
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.updateFigure)
        self.timer.start(100)

    def init_figure(self):
        xaxis = np.arange(0, 100, 1)
        self.values = [0]*100
        yaxis = np.array(self.values)
        self.ax.set_title("Realtime Waveform Plot")
        self.ax.set_xlabel("Time")
        self.ax.set_ylabel("Amplitude")
        self.ax.axis([0, 100, -1.5, 1.5])
        self.line1 = self.ax.plot(xaxis, yaxis, '-')

    def addData(self):
        self.values.append(random.random() * 2 - 1)

    def updateFigure(self):
        self.addData()
        CurrentXAxis = np.arange(len(self.values)-100, len(self.values), 1)
        self.line1[0].set_data(CurrentXAxis, np.array(self.values[-100:]))
        self.ax.axis([CurrentXAxis.min(), CurrentXAxis.max(), -1.5, 1.5])
        self.draw()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    main_widget = QtGui.QWidget()
    l = QtGui.QVBoxLayout(main_widget)
    graph = CustomFigCanvas(main_widget)
    l.addWidget(graph)
    main_widget.show()
    sys.exit(app.exec_())

Screenshot:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM