pyqtgraph中的两个轴图w.r.t时间

Posted

技术标签:

【中文标题】pyqtgraph中的两个轴图w.r.t时间【英文标题】:Two axis plots w.r.t time in pyqtgraph 【发布时间】:2013-09-21 15:49:50 【问题描述】:

有人可以帮助我如何使用 pyqtgraph 创建一个两轴图 w.r.t 时间。例如,绘制速度与扭矩与时间的关系,即时间是 x 轴并且正在移动,速度与扭矩的关系是时间的函数。

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
from numpy import *
from socket import *
import time

app = QtGui.QApplication([])

x = [0,1,2,3,4,5,6,7,8,9];
y = [0,2,4,6,8,10,12,16,18,20];

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()

for i in range(1,20):
    p1 = pw.plotItem
    p2 = pg.ViewBox()
    p1.showAxis('right')
    p1.scene().addItem(p2)
    p2.setGeometry(p1.vb.sceneBoundingRect())
    p1.getAxis('right').linkToView(p2)
    p2.setXLink(p1)
    x.append(i)
    y.append(i*2)
    p1.plot(x)
    #time.sleep(1)    
    p2.addItem(p1.plot(y, pen='b'))
    #time.sleep(1)

【问题讨论】:

听起来您在谈论 3D 线图,对吗?您能否发布您正在寻找的情节类型的示例图片? 感谢您的快速回复。是的,你是对的。我正在寻找 3D 线图。我尝试使用上面的编辑选项附加示例图,但出现错误。所以我已经包含了上面的代码sn-p。我需要的三个解决方案是 1.Z 轴是时间并且正在移动,即旧的历史数据应该出来,只显示新数据(Z 轴的时间范围是固定的) 2.看起来每个实例都重新绘制了绘图,即我在同一框架内看到多个图表 3.此外,图表没有动态更新,即图表框架挂起,仅在最后显示。 您提供了一个带有两个 y 轴的 2D 图(这很好,但与 3D 图不同;有关 3D 示例,请参见示例/GLLinePlotItem.py)。 1,2。绘制的所有数据都是持久的;调用 plot.clear() 删除旧条目。 3. Qt 要求您为每次想要的更新调用 QtGui.QApplication.processEvents(),或者启动事件循环 (QApplication.exec_()) 并通过计时器回调更新绘图。 谢谢卢克。现在我们得到了我们想要的。我们还探索了动态移动 X 轴以在固定的 x 轴框架中仅显示新数据,我们在函数 setXRange 中得到了解决方案。现在情节正在按预期工作。我很欣赏这种形式的讨论。 【参考方案1】:

根据这个论坛上关于这个问题的讨论,下面的代码 sn-p 是我们一直在寻找的,现在满足了我们的要求。这只是一个示例代码,最终将被修改并集成到预期的应用程序中。再次感谢本论坛中的讨论,这些讨论帮助我们找到了正确的解决方案。

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
from numpy import *
from socket import *
import time

app = QtGui.QApplication([])

plot_x = [0,1,2,3,4,5,6,7,8,9];
plot_y = [0,2,4,6,8,10,12,14,16,18];

loopcount = 0;

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()
p1 = pw.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p2.setGeometry(p1.vb.sceneBoundingRect())
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)

def update():
    global pw, pg, loopcount, plot_x, plot_y, p1, p2

    p1.setXRange(loopcount*10, loopcount*10+100)
    p2.setXRange(loopcount*10, loopcount*10+100)

    p1.plot(plot_x)
    p2.addItem(p1.plot(plot_y, pen='b'))

    loopcount = loopcount + 1

    for update in range(loopcount*10, loopcount*10+100):
        plot_x.append(update*loopcount)
        plot_y.append(update*loopcount*2)

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

根据 Luke 的评论改进代码

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
from numpy import *
from socket import *
import time

app = QtGui.QApplication([])

plot_param1 = [0,2,4,6,8,10,12,14,16,18];
plot_param2 = [0,3,6,9,12,15,18,21,24,27];

samplesize = 10;
samples     = range(0,samplesize)
framecount = 0;

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()
p1 = pw.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p2.setGeometry(p1.vb.sceneBoundingRect())
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)

def update():
    global pw, pg, framecount, plot_param1, plot_param2, p1, p2, samples, samplesize

    p1.plot(samples, plot_param1)
    p2.addItem(p1.plot(samples, plot_param2, pen='b'))

    pw.autoRange()

    p1.setXRange(framecount*samplesize, framecount*samplesize+samplesize)
    p2.setXRange(framecount*samplesize, framecount*samplesize+samplesize)

    if framecount == 0:
        flushloop = samplesize
    else:
        flushloop = samplesize+1

    for flush in range(1,flushloop):
        plot_param1.pop(0)
        plot_param2.pop(0)
        samples.pop(0)

    # below code is to prepare for next sample
    framecount = framecount + 1

    for update in range(framecount*samplesize, framecount*samplesize+samplesize):
        plot_param1.append(update*framecount*2)
        plot_param2.append(update*framecount*3)
        samples.append(update)

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

【讨论】:

我发现这有两个问题:1) 数据没有被清除,因此随着绘图积累数据,性能下降得很快。 2) X-range 的增长速度比数据本身慢,因此您永远不会查看最新数据。 感谢您的反馈。我已根据您在上面答案部分的“基于 Luke 的评论的改进代码”中的反馈提供了改进的脚本。旧数据从绘图数据存储中刷新,同时保留在绘图历史记录中。 X 轴正在赶上数据。请查看更新后的脚本,并为任何改进范围提供反馈。【参考方案2】:

这样的事情呢?

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
pg.setConfigOptions(antialias=True)
pg.setConfigOption('background', '#c7c7c7')
pg.setConfigOption('foreground', '#000000')
from pyqtgraph.ptime import time
app = QtGui.QApplication([])

p = pg.plot()
p.setXRange(0,10)
p.setYRange(-10,10)
p.setWindowTitle('Current-Voltage')
p.setLabel('bottom', 'Bias', units='V', **'font-size':'20pt')
p.getAxis('bottom').setPen(pg.mkPen(color='#000000', width=3))
p.setLabel('left', 'Current', units='A',
            color='#c4380d', **'font-size':'20pt')
p.getAxis('left').setPen(pg.mkPen(color='#c4380d', width=3))
curve = p.plot(x=[], y=[], pen=pg.mkPen(color='#c4380d'))
p.showAxis('right')
p.setLabel('right', 'Dynamic Resistance', units="<font>&Omega;</font>",
            color='#025b94', **'font-size':'20pt')
p.getAxis('right').setPen(pg.mkPen(color='#025b94', width=3))

p2 = pg.ViewBox()
p.scene().addItem(p2)
p.getAxis('right').linkToView(p2)
p2.setXLink(p)
p2.setYRange(-10,10)

curve2 = pg.PlotCurveItem(pen=pg.mkPen(color='#025b94', width=1))
p2.addItem(curve2)

def updateViews():
    global p2
    p2.setGeometry(p.getViewBox().sceneBoundingRect())
    p2.linkedViewChanged(p.getViewBox(), p2.XAxis)

updateViews()
p.getViewBox().sigResized.connect(updateViews)

x = np.arange(0, 10.01,0.01)
data = 5+np.sin(30*x)
data2 = -5+np.cos(30*x)
ptr = 0
lastTime = time()
fps = None

def update():
    global p, x, curve, data, curve2, data2, ptr, lastTime, fps
    if ptr < len(x):
        curve.setData(x=x[:ptr], y=data[:ptr])
        curve2.setData(x=x[:ptr], y=data2[:ptr])
        ptr += 1
        now = time()
        dt = now - lastTime
        lastTime = now
        if fps is None:
            fps = 1.0/dt
        else:
            s = np.clip(dt*3., 0, 1)
            fps = fps * (1-s) + (1.0/dt) * s
        p.setTitle('%0.2f fps' % fps)
    else:
        ptr = 0
    app.processEvents()  ## force complete redraw for every plot.  Try commenting out to see if a different in speed occurs.
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)



## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

【讨论】:

如果您对您所做的/更改/编写的内容等发表一些评论,这也将对所有人都有很大帮助。

以上是关于pyqtgraph中的两个轴图w.r.t时间的主要内容,如果未能解决你的问题,请参考以下文章

查找给定多边形 w.r.t 的两个“边界”顶点。已知(光源)点

ggplot2中的分轴图

R:两轴图调整

将时间戳与查询中的日期名称相等,并在 PostgreSQL 查询中获取结果集 w.r.t 日期名称

PyQt4 中的 QThreading PyQtGraph PlotWidgets

w.r.t 的“长”和“短”记分牌是啥? MIO/L1TEX?