So what I'm currently trying to do is to create a class I can use for real time plotting of any kind. In principle I just want to call the class variable and use a command like set_data(x,y). The problem I encountered is that I need to use python threading to update the displayed graphs. But when I use threading like in the code below the pyqtgraph window doesn't respond anymore when executing the while True part at the end of my code where I want to update the plotted graph data. Is there an alternative way to update the graphs instead of my not working thread method? I read about the QtCore timer but this method also crashes like the normal threading I'm using here.
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import random
import threading
import time
from pyqtgraph.dockarea import *
class liveplot(threading.Thread):
def __init__(self, updating_time__s=0.01):
"""
Contructor of the liveplot class
"""
self.app = pg.mkQApp("DockArea Example")
self.win = QtGui.QMainWindow()
self.area = DockArea()
self.win.setCentralWidget(self.area)
self.win.resize(1000, 500)
self.win.setWindowTitle('pyqtgraph example: dockarea')
threading.Thread.__init__(self) # Init thread class
self._lock = threading.Lock() # Needed to prevent data races in threads.
self._stop_thread = False
self.widgetlist = []
self.docklist = []
self.x_data = []
self.y_data = []
self.plotlist = []
self.updateing_time__s = updating_time__s
self._last_measurement_time__s = time.time()
self.start()
def plot(self, widgetnumber, axis, x_data, y_data):
self.plotlist.append(self.widgetlist[widgetnumber].plot(x_data, y_data))
self.x_data = x_data
self.y_data = y_data
def add_widget(self, docktitle="Test", docksize=(500,200), widgettitle="Test"):
d = Dock(docktitle, size=docksize)
w = pg.PlotWidget(title=widgettitle)
d.addWidget(w)
self.docklist.append(d)
self.widgetlist.append(w)
self.area.addDock(d)
def set_data(self, x_data, y_data):
self.x_data = x_data
self.y_data = y_data
self.new_data_available = True
def update_plot_data(self):
# In the end I want it to be as general as possible but in the moment I just want it to work properly
# for the first part so I only have one element in the plotlist.
self.plotlist[0].setData(self.x_data.tolist(), self.y_data.tolist())
def show(self):
self.win.show()
def run(self):
"""
Main
"""
# Run thread until stop() is called
while True:
if self._stop_thread:
break
current_time__s = time.time()
time_since_last_measurement__s = current_time__s - self._last_measurement_time__s
if time_since_last_measurement__s >= self.updateing_time__s:
self._last_measurement_time__s = current_time__s
if len(self.plotlist) > 0:
self.update_plot_data()
def stop(self):
with self._lock:
self._stop_thread = True
x = liveplot()
x.add_widget()
x_dat = np.linspace(0, 10, 100)
y_dat = np.sin(x_dat)
x.add_widget()
x.plot(widgetnumber=0, axis=0, x_data=x_dat, y_data=y_dat)
x.show()
while True:
time.sleep(1)
x_dat = np.roll(x_dat, 1)
x_dat[-1] = x_dat[-2] + 1 # Add a new value 1 higher than the last.
y_dat = np.roll(y_dat, 1)
y_dat[-1] = random.randint(0,100) # Add a new random value.
x.set_data(x_dat, y_dat)