2 votes

Tracé avec pyqtgraph en utilisant des données externes

J'essaie de tracer les données de différents capteurs en temps réel, j'ai donc décidé de tracer les données en utilisant PyQtGraph dans PyQt, afin de le faire fonctionner avec les données de plusieurs capteurs provenant de sources différentes. En cherchant un exemple sur internet, j'en ai trouvé un et j'ai essayé de l'adapter, A cause de QtGui.QApplication.instance().exec_(), qui a pour effet secondaire de bloquer l'exécution du reste du code qui suit. J'ai essayé de gérer l'utilisation de threads en utilisant le Multiprocessing. J'ai pu faire fonctionner le reste du code, mais comment mettre à jour le tracé en utilisant des données externes (Plo2D.update2), j'ai essayé d'utiliser multiprocessing.Queue, mais cela n'a pas fonctionné, au lieu de cela il apparaît que le massage de la fenêtre doit être fermé.

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
from numpy import arange
import pyqtgraph as pg
import sys
import multiprocessing

class Plot2D():
    def __init__(self,):
        self.traces = dict()
        self.app = QtGui.QApplication([])
        self.win = pg.GraphicsWindow(title="Dibujar")
        self.win.resize(1000, 600)
        self.win.setWindowTitle('Ejemplo')
        pg.setConfigOptions(antialias=True)
        #self.canvas = self.win.addPlot(title="Pytelemetry")
        self.waveform1 = self.win.addPlot(title='WAVEFORM1', row=1, col=1)
        self.waveform2 = self.win.addPlot(title='WAVEFORM2', row=2, col=1)

    def start(self):
        if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
            QtGui.QApplication.instance().exec_()

    def set_plotdata(self, name, datax, datay):
        if name in self.traces:
            self.traces[name].setData(datax, datay)
        else:
            if name == '910D':
                self.traces[name] = self.waveform1.plot(pen='c', width=3)
            if name == 'MPU':
                self.traces[name] = self.waveform2.plot(pen='c', width=3)

    def update2(self):
        # Trying to get external data
        ptm1 = globals()['DatExt1']
        ptm2 = globals()['DatExt2']
        while ptm1.empty() is False:
            self.data1 = ptm1.get()
            self.set_plotdata('MPU', self.data1[0], self.data1[1])
            # csvWriterG910D.writerows(Informa)
            # file1.flush()
        while ptm2.empty() is False:
            self.data2 = ptm2.get()
            self.set_plotdata('910D', self.data1[0], self.data1[1])

    def animation(self):
        timer = QtCore.QTimer()
        timer.timeout.connect(self.update2)
        timer.start(60)
        self.start()

# It is thread started from main.py
def ShowData(Data1, Data2): # Data1,Data2 : multiprocessing.Queue
    DatExt1 = Data1
    DatExt2 = Data2
    p = Plot2D()
    p.animation()

le fichier main.py :

    if __name__ == '__main__':

    Data1 = multiprocessing.Queue()
    Data2 = multiprocessing.Queue()

    Plottingdata = Process(target=PlotData.ShowData, args=(Data1, Data2, ))
    Plottingdata.start()

    t = np.arange(-3.0, 2.0, 0.01)
    i = 0.0
    while True:
        s = np.sin(2 * 2 * 3.1416 * t) / (2 * 3.1416 * t + i)
        time.sleep(1)
        Data1.put([t, s])
        i = i + 0.1

Merci d'avance pour votre aide

0voto

eyllanesc Points 79506

Au lieu d'utiliser le MultiProcessing, vous devriez utiliser le MultiThreading, c'est-à-dire créer des threads qui sont responsables de la collecte des données (dans votre exemple, les données d'émulation) et qui envoient ensuite les données à l'interface graphique par des signaux.

PlotData.py

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
import sys

class Plot2D(pg.GraphicsWindow):
    def __init__(self):
        pg.GraphicsWindow.__init__(self, title="Dibujar")
        self.traces = dict()
        self.resize(1000, 600)
        pg.setConfigOptions(antialias=True)
        #self.canvas = self.win.addPlot(title="Pytelemetry")
        self.waveform1 = self.addPlot(title='WAVEFORM1', row=1, col=1)
        self.waveform2 = self.addPlot(title='WAVEFORM2', row=2, col=1)

    def set_plotdata(self, name, x, y):
        if name in self.traces:
            self.traces[name].setData(x, y)
        else:
            if name == "910D":
                self.traces[name] = self.waveform1.plot(x, y, pen='y', width=3)
            elif name == "MPU":
                self.traces[name] = self.waveform2.plot(x, y, pen='y', width=3)

    @QtCore.pyqtSlot(str, tuple)
    def updateData(self, name, ptm):
        x, y = ptm
        self.set_plotdata(name, x, y)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    plot = Plot2D()
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

main.py

import sys

from pyqtgraph.Qt import QtCore, QtGui
import threading
import numpy as np
import time

from PlotData import Plot2D

class Helper(QtCore.QObject):
    changedSignal = QtCore.pyqtSignal(str, tuple)

def create_data1(helper, name):
    t = np.arange(-3.0, 2.0, 0.01)
    i = 0.0
    while True:
        s = np.sin(2 * 2 * 3.1416 * t) / (2 * 3.1416 * t + i)
        time.sleep(.1)
        helper.changedSignal.emit(name, (t, s))
        i = i + 0.1

def create_data2(helper, name):
    t = np.arange(-3.0, 2.0, 0.01)
    i = 0.0
    while True:
        s = np.cos(2 * 2 * 3.1416 * t) / (2 * 3.1416 * t - i)
        time.sleep(.1)
        helper.changedSignal.emit(name, (t, s))
        i = i + 0.1

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    helper = Helper()
    plot = Plot2D()
    helper.changedSignal.connect(plot.updateData, QtCore.Qt.QueuedConnection)
    threading.Thread(target=create_data1, args=(helper, "910D"), daemon=True).start()
    threading.Thread(target=create_data2, args=(helper, "MPU"), daemon=True).start()
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X