Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQtGraph和numpy实时绘图_Python_Arrays_Numpy - Fatal编程技术网

Python PyQtGraph和numpy实时绘图

Python PyQtGraph和numpy实时绘图,python,arrays,numpy,Python,Arrays,Numpy,我目前正在做一个项目,读取8个传感器并绘制实时图形。我使用了Matplotlib,但速度很慢,所以我切换到pyqtgraph。它相对来说非常快。我参考了文档并设计了一个简单的代码来绘制实时数据。 我面临的唯一问题是磁盘空间和cpu使用率急剧增加,因为我让它画了20分钟左右。这是我的密码 from tinkerforge.ip_connection import IPConnection from tinkerforge.bricklet_ptc import BrickletPTC from

我目前正在做一个项目,读取8个传感器并绘制实时图形。我使用了Matplotlib,但速度很慢,所以我切换到pyqtgraph。它相对来说非常快。我参考了文档并设计了一个简单的代码来绘制实时数据。 我面临的唯一问题是磁盘空间和cpu使用率急剧增加,因为我让它画了20分钟左右。这是我的密码

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_()
我听说列表速度慢得多,numpy速度快得多,而且与pyqtgraph兼容得多。因为我对这种编程是新手,所以我无法制作一个numpy数组来读取这些温度读数并绘制图表。我也参考了文档,但没有帮助

我有8个传感器我不知道我应该创建8个不同的numpy数组还是类似于一个多维数组的东西,它接受传感器值和一个实时绘制这些值的函数


如果有人能帮我创建numpy数组而不是列表,我将不胜感激。

因此,如果您想用
np.array
替换列表,您将面临一个主要问题:无法像列表那样直接将数据附加到数组中。一种可能是使用例如
np.hstack
np.vstack
np.column\u stack
np.row\u stack
。下面是一个示例,说明如何使用
np.hstack
更改
updateSensor1
函数:

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()
但是,对于数组,每个“追加”操作都需要将所需内存短期增加一倍,因此您可能会发现,在处理大型数组时,使用列表会更有效

更好的解决方案是生成一个数组(例如,
np.zeros
),该数组与所需的最终输出一样大,例如在绘图20分钟后。这样可以避免创建/销毁阵列。然后,您只需创建另一个计数变量或将时间传递给
updateSensor1
-函数,即可更新和绘制正确的数据,例如:

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()
对于多个传感器,您只需向阵列添加新尺寸,例如,对于8个传感器,创建一个
np.zeros((1200,8))
阵列。我希望这在某种程度上是有帮助的

编辑:

如果您
pop
每个
300s
左右的列表仍希望x轴在时间上继续,则应传递第二个列表或具有x/时间值的数组。我想提出如下建议:

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()

然后,您应该在弹出
tempC1
列表的同时弹出
时间列表。由于参考时间
t0
未更改,因此应始终为您提供正确的时间。

因此,如果要用
np.array
替换列表,您将面临一个主要问题:无法直接将数据以与列表相同的方式附加到数组中。一种可能是使用例如
np.hstack
np.vstack
np.column\u stack
np.row\u stack
。下面是一个示例,说明如何使用
np.hstack
更改
updateSensor1
函数:

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()
但是,对于数组,每个“追加”操作都需要将所需内存短期增加一倍,因此您可能会发现,在处理大型数组时,使用列表会更有效

更好的解决方案是生成一个数组(例如,
np.zeros
),该数组与所需的最终输出一样大,例如在绘图20分钟后。这样可以避免创建/销毁阵列。然后,您只需创建另一个计数变量或将时间传递给
updateSensor1
-函数,即可更新和绘制正确的数据,例如:

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()
对于多个传感器,您只需向阵列添加新尺寸,例如,对于8个传感器,创建一个
np.zeros((1200,8))
阵列。我希望这在某种程度上是有帮助的

编辑:

如果您
pop
每个
300s
左右的列表仍希望x轴在时间上继续,则应传递第二个列表或具有x/时间值的数组。我想提出如下建议:

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()

然后,您应该在弹出
tempC1
列表的同时弹出
时间列表。由于参考时间
t0
未更改,因此应始终为您提供正确的时间。

非常感谢您提供宝贵的教程。不知何故,我提高了我以前的代码的效率,它与列表配合得很好。唯一的问题是我的实时性有一定的时滞(每小时50秒)。你认为Numpy会有助于消除这种时间延迟并使其实时化吗?另外,为了使我的程序更有效率,我尝试在计数器达到300秒时
tempC1.pop(0)
列表。pop功能良好,但x轴保持在0-300。是否有一种方法可以在轴显示实时数据时弹出列表项,即使在列表中的值被弹出后也是如此?如果列表中最多只有300个值,我不认为延迟源自使用列表。查看我关于x轴问题的编辑。非常感谢您提供的宝贵教程。不知何故,我提高了我以前的代码的效率,它与列表配合得很好。唯一的问题是我的实时性有一定的时滞(每小时50秒)。你认为Numpy会有助于消除这种时间延迟并使其实时化吗?另外,为了使我的程序更有效率,我尝试在计数器达到300秒时
tempC1.pop(0)
列表。pop功能良好,但x轴保持在0-300。是否有一种方法可以在轴显示实时数据时弹出列表项,即使在列表中的值被弹出后也是如此?如果列表中最多只有300个值,我不认为延迟源自使用列表。查看我关于x轴问题的编辑。