title: Real-Time-Plotting using pyqtgraph and threading
body: <p>this is a bit longer, the first part is just a description of the problem, the second one the question if my "fix" is correct. </p>
  
  <p>I started with python programming. I created a program that communicates with an Arduino that reads the temperature of a furnace of our melting lab. The temperature is then used in a PID algorithm and an output is set to the Arduino. The communication is done via pyserial. So far, everthing works, including live plotting of the temperature signals, PID-variables and so on. The script includes a the main loop and 3 threads (serial communication, a datashifter that reads from serialport, the set temperature from the QWidget and the output of the PID algorithm. This values are used to create an array for displaying within pyqtgraph. Finally, the third thread shifts the data from the datashifter to the QWidget. </p>
  
  <p>When using my Linux-Notebook, everything works fine, and the GUI never stops updating. In contrast, when using any Windows-Host, i have the problem that some pyqtgraphs stop to refresh. The behavior is strange, because i set all data at more or less the same time, with the same numpy array (just different columns) - some plots refresh longer (hours), some stop earlier (minutes). After searching more or less the hole internet ;-) I think that I found the problem: Its the passing of data from from a thread to the GUI. Some dummy code to explain what's going on:</p>
  
  <pre><code>DataUpdaterToGUI(QThread):
  
  #sets the QWidget from main loop
  def setGUI(self, gui):
      self.gui = gui
  
  def run()
      while True:
          with lock(): # RLock() Instance
             copyArray = self.dataArray[:] # copy the array from the shifter
             self.gui.plot1.copyArray(dataArray[:, 0], copyArray[:, 1])
             self.gui.plot2.copyArray(dataArray[:, 0], copyArray[:, 2])
             # self.gui.update()
             # QApplication.instance().processEvents() 
  </code></pre>
  
  <p>Neither calling self.gui.update() nor processEvents() has any influence on the outcome: The plots stop redrawing after a while (on windows). </p>
  
  <p>Now i have a very simple example, and just want to make sure if I'm using the threading-stuff correctly. It works fine, but I have some questions:</p>
  
  <ul>
  <li>Does the signal-slot approach copy the passed data? </li>
  <li>Why is it not necessary to call the update() method of the QWidget?</li>
  <li>Do I have to use any kind of locks when using signals?</li>
  </ul>
  
  <hr>
  
  <pre><code>class Main(QWidget):
      def __init__(self):
          super().__init__()
  
          self.layout = QGridLayout(self)
          self.graph = pg.PlotWidget()
          self.graph.setYRange(0,1000)
          self.plot = self.graph.plot()
          self.layout.addWidget(self.graph,0,0)
          self.show()
  
      def make_connection(self, data_object):
          data_object.signal.connect(self.grab_data)
  
      @pyqtSlot(object)
      def grab_data(self, data):
          print(data)
          self.plot.setData(data)
  
  
  class Worker(QThread):
      signal = pyqtSignal(object)
  
      def __init__(self):
          super().__init__()
  
      def run(self):
          self.data = [0, 1]
          i = 2
          while True:
              self.data[1] = i
              self.signal.emit(self.data)
              time.sleep(0.01)
              i += 1
  
  if __name__ == "__main__": 
      app = QApplication(sys.argv)
  
      widget = Main()
      worker = Worker()
      widget.make_connection(worker)
      worker.start()
  
      sys.exit(app.exec_())
  </code></pre>