mainImg = pg.ImageItem(rot90(im.light[1][0], 3)) # im.light[1][0] is a np.array float64
gLayout = pg.GraphicsLayout()
view.setCentralItem(gLayout)
mainHist = gLayout.addItem(pg.HistogramLUTItem(mainImg), rowspan=3)
mainBox = gLayout.addViewBox(colspan=3, rowspan=3, lockAspect = True)
yPlot = gLayout.addPlot(rowspan=3)
gLayout.nextRow()
xPlot = gLayout.addPlot(col=1, colspan=3)
xPlot.plot([1,3,2,4,3,5]) # Just random numbers for now
yPlot.plot([1,3,2,4,3,5]) # Just random numbers for now
mainBox.addItem(mainImg)
mainBox.autoRange()
mainBox.setMouseMode(pg.ViewBox.RectMode)
Hello,I'm trying to have 3 plots with different sizes on the screen. A big central one and 2 secondary with image projections and I want the first to occupy most of the screen and the others to be about 1/3 the size. I've tried using rowspan and colspan ona GraphicsLayout but it won't keep the dimensions... =/
Any suggestions?mainImg = pg.ImageItem(rot90(im.light[1][0], 3)) # im.light[1][0] is a np.array float64
gLayout = pg.GraphicsLayout()
view.setCentralItem(gLayout)
mainHist = gLayout.addItem(pg.HistogramLUTItem(mainImg), rowspan=3)
mainBox = gLayout.addViewBox(colspan=3, rowspan=3, lockAspect = True)
yPlot = gLayout.addPlot(rowspan=3)
gLayout.nextRow()
xPlot = gLayout.addPlot(col=1, colspan=3)
xPlot.plot([1,3,2,4,3,5]) # Just random numbers for now
yPlot.plot([1,3,2,4,3,5]) # Just random numbers for now
mainBox.addItem(mainImg)
mainBox.autoRange()
mainBox.setMouseMode(pg.ViewBox.RectMode)
import numpy as npdata = np.random.normal(size=(100,100))import pyqtgraph as pgpg.mkQApp()w = pg.GraphicsLayoutWidget()w.show()v = w.addViewBox(row=0, col=0)p1 = w.addPlot(row=0, col=1)p2 = w.addPlot(row=1, col=0)# restrict size of plot areasw.ci.layout.setColumnMaximumWidth(1, 100)w.ci.layout.setRowMaximumHeight(1, 100)# force central viewbox and side plots to have matching coordinate systemsp1.setYLink(v)p2.setXLink(v)# Show image data and plot image mean axross x/y axesimg = pg.ImageItem(data)v.addItem(img)p1.plot(x=data.mean(axis=0), y=np.arange(0, data.shape[1]))p2.plot(x=np.arange(0, data.shape[1]), y=data.mean(axis=1))
Also, is there a way to lock the mouse mode in RectMode? (I don't want to disable the mouse context menu but I don't want to allow panning...)
Just understand that if we change the internal structure in the future, this code will stop working.v.menu.mouseModes[0].setEnabled(False)v.menu.mouseModes[1].setEnabled(False)
Thanks for the help! It sure send me on the right way! xD
My solution was to grab the resizeEven, recalculate the proportions and set the geometry/preferred size of each graph...
Hello again! xDI'm having problems with the YLink... It's not really aligned with the viewbox (view image)Is there a way to force realign? Or something I could do?
# Import PySide Qt elementsimport PySidefrom PySide.QtGui import *from PySide.QtCore import *import pyqtgraph as pg
# Import pylab and sysfrom pylab import *import sys
# PyQtGraphimport pyqtgraph as pg
class mainWindow(QMainWindow): def __init__(self): super(mainWindow, self).__init__()
self.central = central() self.setCentralWidget(self.central) def resizeEvent(self, event): self.central.layout.resized()
class central(QWidget): def __init__(self): super(central, self).__init__() self.setFocus() self.layout = centralLayout() self.setLayout(self.layout)
class centralLayout(QGridLayout): def __init__(self): super(centralLayout, self).__init__() view = pg.GraphicsView() self.im = images() self.gLayout = pg.GraphicsLayout() view.setCentralItem(self.gLayout) self.label = pg.LabelItem(justify='center') self.label.hide() self.gLayout.addItem(self.label, row = 1, col = 1)
self.mainBox = myViewBox(self, lockAspect = True) self.mainBox.images = {} self.gLayout.addItem(self.mainBox, row = 0, col = 0) self.yPlot = self.gLayout.addPlot(row=0, col=1) self.yPlot.invertY() self.yPlot.setYLink(self.mainBox) self.yPlot.setAutoVisible(x=True) self.yPlot.showGrid(x=True, y=True) self.xPlot = self.gLayout.addPlot(row = 1, col = 0) self.xPlot.setXLink(self.mainBox) self.xPlot.setAutoVisible(y=True) self.xPlot.showGrid(x=True, y=True) self.mainHist = pg.HistogramLUTItem() self.gLayout.addItem(self.mainHist, row = 0, col = 2, rowspan = 2)
self.mainBox.autoRange() self.mainBox.scene().sigMouseMoved.connect(self.mainBox.mouseMoved)
view.show()
self.show(0, 100) self.addWidget(view)
def show(self, priority, alpha, show=True): image = 1000 * rand(1000,1000) imgMedian = median(image) img = pg.ImageItem((image), levels = (imgMedian, 3*imgMedian), opacity = alpha/100.) img.setZValue(priority) img.setData(0, key) self.mainBox.addItem(img) self.mainBox.autoRange() self.mainHist.setImageItem(img) self.mainHist.setHistogramRange(imgMedian, 3*imgMedian) self.mainHist.setLevels(imgMedian, 3*imgMedian) self.xPlot.plot(image.sum(1)) self.yPlot.plot(x = image.sum(0), y = indices(image.sum(0).shape)[0] )
def resized(self): range = self.mainBox.viewRange() X, Y = range[0][1], range[1][1] relax = 0.05 * X # Set size for between graphs proj = 0.3 * Y # Set size of projections width = X + relax + 2*proj totalSize = self.gLayout.layout.geometry() # Get widget geometry # Scales dimensions based on viebox image and widget size scale = totalSize.width() / width newX = X * scale newY = Y * scale newRelax = relax * scale / 4 newProj = proj * scale heighRelax = (totalSize.height() - (newY + newProj)) / 3 # Set new geometries and define a preferred size self.gLayout.layout.itemAt(0, 0).setGeometry(newRelax, heighRelax, newX, newY) self.gLayout.layout.itemAt(0, 0).setPreferredSize(self.gLayout.layout.itemAt(0, 0).geometry().size()) self.gLayout.layout.itemAt(0, 0).updateGeometry() self.gLayout.layout.itemAt(1, 0).setGeometry(newRelax, (newY + 2*heighRelax), newX, newProj) self.gLayout.layout.itemAt(1, 0).setPreferredSize(self.gLayout.layout.itemAt(1, 0).geometry().size()) self.gLayout.layout.itemAt(1, 0).updateGeometry() self.gLayout.layout.itemAt(0, 1).setGeometry((newX + 2*newRelax), heighRelax, newProj, newY) self.gLayout.layout.itemAt(0, 1).setPreferredSize(self.gLayout.layout.itemAt(0, 1).geometry().size()) self.gLayout.layout.itemAt(0, 1).updateGeometry()# self.gLayout.layout.itemAt(0, 2).setGeometry(totalSize.width()-120-newRelax, heighRelax, newProj, (totalSize.height()-2*heighRelax) )# self.gLayout.layout.itemAt(0, 2).setPreferredSize(self.gLayout.layout.itemAt(0, 2).geometry().size())# self.gLayout.layout.itemAt(0, 2).updateGeometry() class myViewBox(pg.ViewBox): def __init__(self, par, *args, **kwds): self.par = par pg.ViewBox.__init__(self, *args, **kwds) self.setMouseMode(self.RectMode) self.invertY()
self.vLine = pg.InfiniteLine(angle=90, movable=False) self.vLine.setZValue(100) self.vLine.hide() self.hLine = pg.InfiniteLine(angle=0, movable=False) self.hLine.setZValue(100) self.vLine.hide() self.addItem(self.vLine, ignoreBounds=True) self.addItem(self.hLine, ignoreBounds=True) self.dragVLine = pg.InfiniteLine(angle=90, movable=False) self.dragVLine.setZValue(100) self.dragVLine.hide() self.dragHLine = pg.InfiniteLine(angle=0, movable=False) self.dragHLine.setZValue(100) self.dragHLine.hide() self.addItem(self.dragVLine, ignoreBounds=True) self.addItem(self.dragHLine, ignoreBounds=True)
def mouseDragEvent(self, ev): if ev.button() == Qt.RightButton: ev.ignore() else: self.dragVLine.setPos(self.mapToView(ev.buttonDownPos()).x()) self.dragVLine.show() self.dragHLine.setPos(self.mapToView(ev.buttonDownPos()).y()) self.dragHLine.show()
pg.ViewBox.mouseDragEvent(self, ev)
if ev.isFinish(): self.vLine.hide() self.hLine.hide() self.dragVLine.hide() self.dragHLine.hide()
def mouseMoved(self, ev):# Make show only inside image, make show pixel value as well! pos = ev if self.sceneBoundingRect().contains(pos): mousePoint = self.mapSceneToView(pos) index = [int(mousePoint.x()), int(mousePoint.y())] if index[0] > 0 and index[1] > 0 and index[0] < self.viewRange()[0] and index[1] < self.viewRange()[1]: self.par.label.show() self.par.label.setText("<span style='font-size: 14pt'><br><br><br> x = %4.0f <br> y = %4.0f <br>" % (mousePoint.x(), mousePoint.y())) else: self.par.label.hide() self.vLine.setPos(mousePoint.x()) self.vLine.show() self.hLine.setPos(mousePoint.y()) self.hLine.show() else: self.par.label.hide() self.vLine.hide() self.hLine.hide()
def main(): app = QApplication.instance() # checks if QApplication already exists if not app: # create QApplication if it doesnt exist app = QApplication(sys.argv) main = mainWindow() main.show()# sys.exit(app.exec_()) app.exec_()
if __name__ == '__main__': main()
img.setData(0, 'rand img')