首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyQtGraph与numpy实时图

PyQtGraph与numpy实时图
EN

Stack Overflow用户
提问于 2016-09-09 08:07:10
回答 1查看 2.2K关注 0票数 1

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

代码语言:javascript
复制
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数组而不是列表,我将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-09 09:11:59

因此,如果您想用np.array替换您的列表,您将面临一个主要问题:不可能以与列表相同的方式直接将数据追加到数组。一种可能是使用例如np.hstacknp.vstacknp.column_stacknp.row_stack。下面是一个如何使用updateSensor1更改np.hstack函数的示例

代码语言:javascript
复制
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-function,以便更新和绘制正确的数据,例如:

代码语言:javascript
复制
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/时间值。我建议如下:

代码语言:javascript
复制
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()

然后,您应该在弹出times列表的同时弹出tempC1列表。由于参考时间t0没有更改,这应该总是给出正确的时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39406768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档