【问题标题】:pyqtgraph: synchronize scaling of axes in different plotspyqtgraph:在不同的图中同步轴的缩放
【发布时间】:2017-11-18 11:23:46
【问题描述】:

我想同步几个 pyqtgraph 图的 X 轴。当用户通过鼠标交互重新缩放 X 轴时(例如,鼠标在 x 轴上时滚轮)我想将相同的更改分配给所有其他图。那么我该怎么做呢?

我从下面的基本示例中导出了一个最小化的代码。

我是否必须覆盖w1w2viewRangeChanged() 函数?

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

from pyqtgraph.dockarea import *


win = QtGui.QMainWindow()
area = DockArea()
win.setCentralWidget(area)
win.resize(1000,500)
win.setWindowTitle('pyqtgraph example: dockarea')


d1 = Dock("Dock1")
d2 = Dock("Dock2")
area.addDock(d1, 'bottom')
area.addDock(d2, 'bottom', d1)

w1 = pg.PlotWidget(title="Dock 1 plot")
w1.plot(np.random.normal(size=100))
d1.addWidget(w1)

w2 = pg.PlotWidget(title="Dock 2 plot")
w2.plot(np.random.normal(size=100))
d2.addWidget(w2)

win.show()

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

此问题有后续here 对此问题的另一个答案。

【问题讨论】:

    标签: python pyqtgraph


    【解决方案1】:

    我们需要使用 sigRangeChanged 信号并将其连接到一个插槽,问题是范围的变化另一个项目会产生信号 sigRangeChanged 等等产生一个无限循环,要解决这个问题你必须先断开这些信号进行修改并将它们重新连接到最终版本。

    w1.sigRangeChanged.connect(onSigRangeChanged)
    w2.sigRangeChanged.connect(onSigRangeChanged)
    
    def onSigRangeChanged(r):
        w1.sigRangeChanged.disconnect(onSigRangeChanged)
        w2.sigRangeChanged.disconnect(onSigRangeChanged)
        if w1 == r:
            w2.setRange(xRange=r.getAxis('bottom').range)
        elif w2 == r:
            w1.setRange(xRange=r.getAxis('bottom').range)
    
        w1.sigRangeChanged.connect(onSigRangeChanged)
        w2.sigRangeChanged.connect(onSigRangeChanged)
    

    例子:

    import pyqtgraph as pg
    from pyqtgraph.Qt import QtCore, QtGui
    import numpy as np
    from pyqtgraph.dockarea import *
    import sys
    
    
    def onSigRangeChanged(r):
        w1.sigRangeChanged.disconnect(onSigRangeChanged)
        w2.sigRangeChanged.disconnect(onSigRangeChanged)
        if w1==r:
            w2.setRange(xRange=r.getAxis('bottom').range)
        elif w2 == r:
            w1.setRange(xRange=r.getAxis('bottom').range)
    
        w1.sigRangeChanged.connect(onSigRangeChanged)
        w2.sigRangeChanged.connect(onSigRangeChanged)
    
    app = QtGui.QApplication(sys.argv)
    
    win = QtGui.QMainWindow()
    area = DockArea()
    win.setCentralWidget(area)
    win.resize(1000,500)
    win.setWindowTitle('pyqtgraph example: dockarea')
    
    
    d1 = Dock("Dock1")
    d2 = Dock("Dock2")
    area.addDock(d1, 'bottom')
    area.addDock(d2, 'bottom', d1)
    
    w1 = pg.PlotWidget(title="Dock 1 plot")
    it=w1.plot(np.random.normal(size=100))
    
    d1.addWidget(w1)
    
    w2 = pg.PlotWidget(title="Dock 2 plot")
    w2.plot(np.random.normal(size=100))
    d2.addWidget(w2)
    
    w1.sigRangeChanged.connect(onSigRangeChanged)
    w2.sigRangeChanged.connect(onSigRangeChanged)
    
    win.show()
    
    sys.exit(app.exec_())
    

    【讨论】:

      【解决方案2】:

      更好,

      可以使用 blockSignals 代替断开然后重新连接信号。

      这是同步任意数量的绘图的通用方法:

      syncedPlots = [w1, w2, w3] # put as many plots as you wish
      
      def onSigRangeChanged(r):
          for g in syncedPlots:
              if g !=r :
                  g.blockSignals(True)
                  g.setRange(xRange=r.getAxis('bottom').range)
                  g.blockSignals(False)
      
      for g in syncedPlots:
           g.sigRangeChanged.connect(onSigRangeChanged)
      

      【讨论】:

        【解决方案3】:

        this question有更好的答案:

        我们可以直接链接坐标轴,而不是连接到 sigRangeChanged 事件 按 w2.setXLink(w1) 缩放。

        【讨论】:

        猜你喜欢
        • 2017-11-20
        • 2019-12-13
        • 2019-05-31
        • 2018-08-22
        • 1970-01-01
        • 1970-01-01
        • 2016-10-13
        • 2013-09-22
        • 2021-11-07
        相关资源
        最近更新 更多