How to plot real time EMG signals without delay?

665 views
Skip to first unread message

Igor Muniz

unread,
Jul 25, 2016, 10:52:35 AM7/25/16
to pyqtgraph
Hi guys,

I'm trying to plot a real time signal with python and PyQtGraph has improved the speed a lot, but still with some delay. The data comes from a DLL and it's store in a NumPy Vector.
I wan't to plot this buffer every 0.1s with 100 points(the signal has 1kHz sampling rate). At the beginning this seems to work but after few seconds starts to get behind the plot.

This is part of my code:

def coleta():
global cnt
global t

nsample = c_ulong(int(0.1 * sampleRate.value))

status = emgSampleNSeconds(handle.value, 50)

if status == 0:
print("Inicia a amostragem")
else:
print("Não foi possível iniciar a amostragem")
emgIsSampling(handle.value, byref(isSampling))


canal = c_ulong(0)
emgbuffer = (c_double * nsample.value)()




emgDataPlot = np.zeros(10000, dtype=float)

curve1 = p1.plot(emgDataPlot, pen='r')
sleepVar = 0.1
pltStart = pg.ptime.time()
while isSampling:
time.sleep(sleepVar)
emgGetRealUnitDataBlock(handle.value, canal.value, emgbuffer, byref(nsample))
now = time.time()
for value in emgbuffer:
emgDataPlot = np.append(emgDataPlot, value)
if len(emgDataPlot) > sampleRate.value * 10:
emgDataPlot = np.delete(emgDataPlot, 0)

if t == 0:
p1.enableAutoRange('xy', False) ## stop auto-scaling after the first data set is plotted

t += 1

curve1.setData(emgDataPlot)
app.processEvents()

#print(t)
emgIsSampling(handle.value, byref(isSampling))

#p1.enableAutoRange(True, True)
print(pltStart - pg.ptime.time())

What I need to do?
Thanks.

vas...@gmail.com

unread,
Jul 25, 2016, 2:14:27 PM7/25/16
to pyqt...@googlegroups.com
Hi.

I think that you need to put all pyqtgraph and other graphic stuff (including window initialization, processEvents etc.) in a separate thread and to plot a shared data you have every 0.1s. Look at FuncThread class at bottom of page http://softwareramblings.com/2008/06/running-functions-as-threads-in-python.html, could save you a time. So, one thread for graphic stuff, one or calculation.

Good luck,
Vasilije

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/f3c66f2c-5c13-4b2b-b442-f55aaeda21c7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

vas...@gmail.com

unread,
Jul 25, 2016, 2:18:21 PM7/25/16
to pyqt...@googlegroups.com
.replace('one or calculation', 'other one for a calculation')

vas...@gmail.com

unread,
Jul 26, 2016, 11:13:42 AM7/26/16
to pyqt...@googlegroups.com
You could start with something like this, just use collectData function to calculate your data and put it to self.collected_data variable:

import pyqtgraph
import numpy
import threading
import time

class FuncThread(threading.Thread):
 def __init__(self,target,*args):
  self._target=target
  self._args=args
  threading.Thread.__init__(self)
 def run(self):
  self._target(*self._args)

class MainApp(object):
 def __init__(self):
  plot_loop_time = 0.1
  self.sleep_time = 0.001
  self.number_of_points = 100
  self.collected_data = numpy.zeros([self.number_of_points])
  app = pyqtgraph.mkQApp()
  self.graphics_layout_widget = pyqtgraph.GraphicsLayoutWidget()
  self.graphics_layout_widget.show() 
  plot = self.graphics_layout_widget.addPlot()
  plot.setRange(yRange=(-200,200),disableAutoRange=True)
  cd = FuncThread(self.collectData)
  cd.start()
  current_time = time.time()
  while self.graphics_layout_widget.isVisible():
   time.sleep(self.sleep_time)
   plot.plot(self.collected_data)
   app.processEvents()
   while time.time() - current_time < plot_loop_time:
    time.sleep(self.sleep_time)
   plot.clear()
   current_time = time.time()
  
 def collectData(self):
  while self.graphics_layout_widget.isVisible():
   self.collected_data += numpy.random.uniform(-1, 1, size=self.number_of_points)
   time.sleep(self.sleep_time)

MainApp()



Reply all
Reply to author
Forward
0 new messages