I need to plot an continuous input using pyqtgraph, so I use a circular buffer to hold the data. I use deque with maxlen to do the job. (Python 2.7, numpy 1.9.2, pyqtgraph 0.9.10)
from collections import deque
def create_cbuffer(self):
buffer_len = self.BUFFER_LEN*self.number_of_points
data = [0]*buffer_len # buffer_len = 160k
self.cbuffer[0] = deque(data, maxlen=buffer_len)
buffer_len = self.BUFFER_LEN
data = [0]*buffer_len
self.cbuffer[1] = deque(data, maxlen=buffer_len)
After that I use it like this:
import time
def update_cbuffer(self):
data_points, data = data_feeds() # data get every 16ms as lists
start_t = time.time()
self.cbuffer[0].extend(data_points) # Thanks to @PadraicCunningham
# for k in xrange(0, self.number_of_points):
# self.cbuffer[0].append(data_points[k])
self.cbuffer[1].append(data)
fin_t = time.time() - start_t
setup plot as:
self.curve[0] = self.plots[0].plot(self.X_AXIS,
[0]*self.BUFFER_LEN*self.number_of_points,
pen=pg.intColor(color_idx_0),name='plot1')
self.curve[1] = self.plots[1].plot(self.X_AXIS_2, [0]*self.BUFFER_LEN,
pen=pg.intColor(color_idx_1),name='plot2')
update plot as:
def update_plots(self):
self.curve[0].setData(self.X_AXIS, self.cbuffer[0])
self.curve[0].setPos(self.ptr, 0)
self.curve[1].setData(self.X_AXIS_2, self.cbuffer[1])
self.curve[1].setPos(self.ptr, 0)
self.ptr += 0.016
Then I call it using QTimer:
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.update_cbuffer)
self.timer.timeout.connect(self.update_plots)
self.timer.start(16)
The Question is:
1. When I plot it, it seems to be much slower than 16ms. Any ideas to speed it up?
2. When I time the update_plots() using time.time() and calculate its average run time (total_time/number_of_runs), it increases gradually, I trying to understand the reason behind it.
Any suggestions? I am new to Python, I could make some mistakes in the code, please do not hesitate to point it out. Thank you for your help in advance.
p.s I've try different circular buffers as suggested in efficient circular buffer?
class Circular_Buffer():
def __init__(self, buffer_len, data_type='float'):
if data_type == 'int':
self.__buffer = np.zeros(buffer_len, dtype=int)
else:
self.__buffer = np.zeros(buffer_len)
self.__counter = 0
def append(self, data):
self.__buffer = np.roll(self.__buffer, -1)
self.__buffer[-1] = data
def get(self):
return self.__buffer
But it turns out to be much slower in my case.
I've also try this:
class CB_list():
def __init__(self, buffer_len):
self.__buffer = [0]*buffer_len
def append(self, data):
self.__buffer = self.__buffer[1:]
self.__buffer.append(data)
def get(self):
return self.__buffer
It performs similar as deque, so I stick with deque.
EDIT: Sorry I made a mistake yesterday. I've already correct it on the code.
data = [0]*buffer_len # buffer_len = 16k <--- Should be 160k instead