问题
I'm trying to plot data of diferentes sensors en realtime,so I decided to plot the data using PyQtGraph in PyQt, in order to make it work with several sensor's data from differnte sources. Searching example on the internet, i found one and i tried to adapt it , Because of QtGui.QApplication.instance().exec_(), which carries the inconvenient side effect of blocking the execution of the rest of the code after it. I tried to manage to used threads using Multiproccessing. I could make the rest of the code works, but how coud I update the plot using external data (Plo2D.update2),I tried to used multiprocessing.Queue , but I didn't work, instead appears massage of the window must be closed.
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()
the 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
thanks ind advanced for help
回答1:
Instead of using MultiProcessing you should use MultiThreading, that is, create threads that are responsible for collecting data (in your example emulate data) and then send the data to the GUI by signals.
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_()
来源:https://stackoverflow.com/questions/50314924/plotting-with-pyqtgraph-using-external-data