为实时数据绘图实现 pyqtgraph
Posted
技术标签:
【中文标题】为实时数据绘图实现 pyqtgraph【英文标题】:implementing pyqtgraph for live data graphing 【发布时间】:2013-07-30 20:14:58 【问题描述】:我正在尝试获取数据的实时图,因为它正在由使用 pyqtgraph 的仪器收集。
数据收集由主进程处理,然后通过连接传递给绘制它的子进程。我只是想传递新数据并在传递新数据时更新它。
我试图通过将读取的连接放入 Qt Timer 更新循环中来实现这一点,但是我很难在连续的更新周期之间传递图形数据(我想附加到它)。我从下面的代码中省略了,但基本上我想加入连续的大量 connData,我认为使用全局会起作用,但由于某种原因我无法在这里实现。
编辑1:我与pyqtgraph示例比较的问题似乎是将数据传递给Qtimer的更新过程,我得到:
NameError:未定义全局名称“CurveData”
我尝试这样做而不是使用 pyqtgraph 的多处理模块的原因是我不想每次都通过连接传递整个数据集(我认为这是必要的)。谢谢!
编辑 2:在某处是否有 pyqtgraph.multiprocess 的文档?
(这是提供的原始代码)
import multiprocessing
import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import sys
import os
def MakeGraph(conn):
win = pg.GraphicsWindow(title = "test")
win.resize(300,300)
p1 = win.addPlot(title = "test")
curve = p1.plot(pen = 'y')
timer = QtCore.QTimer()
def Update():
try:
ConnData = conn.recv()
ConnData = [float(i) for i in ConnData]
curve.setData(ConnData)
except EOFError:
print "Graph connection closed\n"
timer.stop()
QtGui.QApplication.quit()
timer.timeout.connect(Update)
timer.start(0)
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
修改版:
import multiprocessing
import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import sys
import os
def MakeGraph(conn):
win = pg.GraphicsWindow(title = "test")
win.resize(300,300)
p1 = win.addPlot(title = "test")
curve = p1.plot(pen = 'y')
timer = QtCore.QTimer()
CurveData = []
def Update():
global CurveData
try:
ConnData = conn.recv()
ConnData = [float(i) for i in ConnData]
CurveData = np.append(CurveData,ConnData)
curve.setData(CurveData)
except EOFError:
print "Graph connection closed\n"
timer.stop()
QtGui.QApplication.quit()
timer.timeout.connect(Update)
timer.start(0)
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
【问题讨论】:
【参考方案1】:您没有解释发布的示例有什么不适用的地方。有错误信息吗?进程是否无法接收消息?情节结果是否与您的预期有所不同?
作为最初的答案,我将推荐一种不同的方法:使用 pyqtgraph 的内置多处理功能。如果您从主进程运行此代码,它将为您提供绘图窗口和在新进程中运行的曲线的代理。您在代理上调用的任何方法都将转发到远程进程:
import pyqtgraph as pg
pg.mkQApp()
# Create remote process with a plot window
import pyqtgraph.multiprocess as mp
proc = mp.QtProcess()
rpg = proc._import('pyqtgraph')
plotwin = rpg.plot()
curve = plotwin.plot(pen='y')
# create an empty list in the remote process
data = proc.transfer([])
# Send new data to the remote process and plot it
# We use the special argument _callSync='off' because we do
# not want to wait for a return value.
data.extend([1,5,2,4,3], _callSync='off')
curve.setData(y=data, _callSync='off')
请注意,我们在此处创建的所有对象——rpg、plotwin、curve 和 data——都是远程进程中真实对象的代理。因此,您可以使用通常的 pyqtgraph 类执行的几乎所有操作也可以使用这些对象完成,并且结果将出现在远程进程中。例如:
# Local code:
win = pg.GraphicsWindow()
p1 = win.addPlot()
p2 = win.addPlot()
# Remote code:
win = rpg.GraphicsWindow()
p1 = win.addPlot()
p2 = win.addPlot()
这两个示例的唯一区别是起点——pg 用于本地 pyqtgraph 模块,而 rpg 用于远程模块。
【讨论】:
谢谢,你的例子对我有用,我可以在我的过程中实现它,它看起来也更优雅。但是,我想知道我可以以与例如相同的方式调用其中的哪些。 pyqtgraph 示例中的“pg.GraphicsWindow”,如果我想添加标题或更多图 我在为多个 QtProcess 实现进程时遇到了一些问题。我把 put from proc = mp.QtProcess() ..to.. data = proc.transfer([]) 放到一个循环中,这样我就有了每个对象的列表。这主要是有效的,但有时它会停止,我无法按 ctrl-c 退出。是否有更稳定的方法来处理生成多个 QtProcess-es?谢谢 听起来像一个错误。作为一种解决方法,为什么不在一个进程中创建多个图呢?无论如何,这似乎是一种更好的方法。 我正在尝试运行这个示例,但我得到了socket.error: [Errno 48] Address already in use
。显然这条线是proc = mq.QTProcess()
。 @Luke 有什么建议吗?
最近在 github 上的开发分支中有一个提交,可能已经解决了这个问题。试试看,如果它仍然坏掉,然后发布到邮件列表或打开一个 github 问题。以上是关于为实时数据绘图实现 pyqtgraph的主要内容,如果未能解决你的问题,请参考以下文章