PyQtGraph and numpy realtime plot
<p>I am currently making a project that reads 8 sensors and plots real time graphs. I have used Matplotlib but it was slow so I switched to pyqtgraph. It is comparatively very fast. I have refered to the documentations and designed a simple code that plots live data. 
The only problem I am facing is the diskspace and cpu usage increases drastically as i let it draw for 20minutes or so.  Here is my code.</p>

<pre><code>from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_ptc import BrickletPTC

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1280,720)
win.setWindowTitle('Live Temperature Data')
#Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)


p1 = win.addPlot(title = 'Sensor1')
curve1 = p1.plot(pen = '#00A3E0')
p1.setLabel('left', "Temperature", units='Â°C')
p1.setLabel('bottom', "Time", units= 's')
p1.setDownsampling(auto=True,mode='peak')
p1.setClipToView(True)
p1.showGrid(x=True, y=True)

tempC1 = []

def updateSensor1():
    global curve1, tempC1, indx1, p1

    ipcon = IPConnection() # Create IP connection
    ptc1 = BrickletPTC(UID1, ipcon) # S1 
    ipcon.connect(HOST, PORT) # Connect to brickd 
    temperature1 = ptc1.get_temperature()

    dataArray1=str(temperature1/100).split(',')
    temp1 = float(dataArray1[0])
    tempC1.append(temp1)

    curve1.setData(tempC1)
    app.processEvents()


timer1 = QtCore.QTimer()
timer1.timeout.connect(updateSensor1)
timer1.start(1000)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_'):
        QtGui.QApplication.instance().exec_()
</code></pre>

<p>I heard lists are much slower and numpy is really fast and much more compatible with pyqtgraph. Since I am new to this programming stuff I am unable to make a numpy array that takes these temperature readings and plots the graph. I have also referred to the documentation but it didn't help</p>

<p>P.s sicne I have 8 sensors I have no idea should I create 8 different numpy arrays or something like one multidimensional array that takes sensor values and a function that plots these values in real time</p>

<p>I'd be grateful if someone can help me creating numpy arrays instead of lists.</p>

<p>So if you want to replace your list with an <code>np.array</code> you will face one major issue: It is not directly possible to append data to an array the same way as with a list. One possibility is to use e.g. <code>np.hstack</code>, <code>np.vstack</code>, <code>np.column_stack</code> or <code>np.row_stack</code>. Here is an example how you could alter your <code>updateSensor1</code> function using <code>np.hstack</code>:</p>

<pre><code>tempC1 = np.array(())

def updateSensor1():
    global curve1, tempC1, indx1, p1

    ipcon = IPConnection() # Create IP connection
    ptc1 = BrickletPTC(UID1, ipcon) # S1 
    ipcon.connect(HOST, PORT) # Connect to brickd 
    temperature1 = ptc1.get_temperature()

    dataArray1=str(temperature1/100).split(',')
    temp1 = np.array((dataArray1[0])).astype(np.float32)
    tempC1 = np.hstack((tempC1,temp1))

    curve1.setData(tempC1)
    app.processEvents()
</code></pre>

<p>However, for arrays each "append" action requires short-term doubling of required memory, so you will probably find that using a list will be more efficient when you will deal with large arrays. </p>

<p>A better solution is to generate an array (e.g. <code>np.zeros</code>) that is as large as your desired final output, for example after 20 minutes of plotting. That way you can avoid array creation/destruction. Then you just need to create another count-variable or pass the time to your <code>updateSensor1</code>-function in order to update and plot the right data, e.g.:</p>

<pre><code>tempC1 = np.zeros((1200))
count = 0

def updateSensor1():
    global curve1, tempC1, indx1, p1, count

    ipcon = IPConnection() # Create IP connection
    ptc1 = BrickletPTC(UID1, ipcon) # S1 
    ipcon.connect(HOST, PORT) # Connect to brickd 
    temperature1 = ptc1.get_temperature()

    dataArray1=str(temperature1/100).split(',')
    temp1 = float(dataArray1[0])
    tempC1[count] = temp1

    curve1.setData(tempC1[::count])
    count += 1
    app.processEvents()
</code></pre>

<p>For multiple sensors, you can just add new dimensions to your array, e.g. for 8 sensors, create a <code>np.zeros((1200,8))</code> array. I hope this was helpful in some way...</p>

<p><strong>EDIT:</strong></p>

<p>If you <code>pop</code> the list each <code>300s</code> or so and still want the x-axis to continue in time you should pass a second list or array with x/time values. I would suggest something like:</p>

<pre><code>import time

times = []
t0 = time.time()

def updateSensor1():
    global curve1, tempC1, indx1, p1, times, t0

    ipcon = IPConnection() # Create IP connection
    ptc1 = BrickletPTC(UID1, ipcon) # S1 
    ipcon.connect(HOST, PORT) # Connect to brickd 
    temperature1 = ptc1.get_temperature()

    dataArray1=str(temperature1/100).split(',')
    temp1 = float(dataArray1[0])
    tempC1.append(temp1)
    times.append(time.time()-t0)

    curve1.setData(times,tempC1)
    app.processEvents()
</code></pre>

<p>Then you should just pop the <code>times</code> list the same time you pop your <code>tempC1</code> list. Since the reference time <code>t0</code> is not changed this should give you always the correct time.</p>

python arrays numpy