I am trying to add GraphicsLayoutWidget
and LinearRegionItem
, that two ratio is 4:1 or m:n, but I don't found any layout in pygtgraph
.So I try to the code like below, but unfortunately it don't work and cast out traceback error info.
code
import pyqtgraph as pg
import numpy as np
from PyQt5.QtWidgets import *
class Chart(pg.GraphicsLayoutWidget):
def __init__(self):
super().__init__()
self.data = np.linspace(0, 2*np.pi, 100)
self.data = np.sin(self.data)
self.p = self.addPlot(y=self.data)
class LR(pg.GraphicsLayoutWidget):
def __init__(self, target):
super().__init__()
self.p = self.addPlot() # type:pg.PlotItem
self.target = target # type: pg.PlotItem
rg = (target.data[0], target.data[-1])
self.p.setXRange(rg[0], rg[1], padding=0)
self.lr = pg.LinearRegionItem([rg[0], rg[1]])
self.lr.sigRegionChanged.connect(self.onLRChanged)
self.p.addItem(self.lr)
def onLRChanged(self):
print(self.target, self.lr.getRegion())
self.target.setXRange(*self.lr.getRegion())
class Win(QWidget):
def __init__(self):
super().__init__()
lay = QVBoxLayout()
self.chart = Chart()
self.lr = LR(self.chart)
lay.addWidget(self.chart)
lay.addWidget(self.lr)
lay.setStretch(0, 4)
lay.setStretch(1, 1)
self.setLayout(lay)
app = QApplication([])
win = Win()
win.show()
app.exec()
image
error
The traceback info will show when user drag LinearRegionItem
line in both side of the bottom graph(plot)
environment
Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Name: pyqtgraph Version: 0.12.2
Name: numpy Version: 1.20.3
Name: PyQt5 Version: 5.15.4
The problem has nothing to do with the stretch factor but setting the range to the GraphicsLayoutWidget that expects a QRect, instead of the PlotItem that expects a tuple causing that exception. On the other hand you can improve how to place the initial range based on the range of the data, also it is better to use signals.
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
import pyqtgraph as pg
import numpy as np
class Chart(pg.GraphicsLayoutWidget):
def __init__(self, xdata, ydata):
super().__init__()
self.p = self.addPlot(x=xdata, y=ydata)
class LR(pg.GraphicsLayoutWidget):
range_changed = pyqtSignal(float, float)
def __init__(self, xmin, xmax):
super().__init__()
self.lr = pg.LinearRegionItem(values=(xmin, xmax))
self.p = self.addPlot()
self.p.addItem(self.lr)
self.lr.sigRegionChanged.connect(self.handle_region_changed)
def handle_region_changed(self, item):
self.range_changed.emit(*item.getRegion())
class Win(QWidget):
def __init__(self):
super().__init__()
xdata = np.linspace(0, 2 * np.pi, 100)
ydata = np.sin(xdata)
self.chart = Chart(xdata, ydata)
self.lr = LR(xdata.min(), xdata.max())
self.lr.range_changed.connect(self.chart.p.setXRange)
lay = QVBoxLayout(self)
lay.addWidget(self.chart, stretch=4)
lay.addWidget(self.lr, stretch=1)
def main():
app = QApplication([])
win = Win()
win.show()
app.exec()
if __name__ == "__main__":
main()