#!/usr/bin/env python # -*- coding: utf-8 -*- """ Demonstrates a variety of uses for ROI. This class provides a user-adjustable region of interest marker. It is possible to customize the layout and function of the scale/rotate handles in very flexible ways. """ #import initExample ## Add path to library (just for examples; you do not need this) import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui import numpy as np class BeamMark(pg.ROI): """A crosshair ROI whose position is at the center of the crosshairs. By default, it is scalable, rotatable and translatable.""" def __init__(self, pos=None, size=None, parent=None, **kargs): #self._size=size #self._pos=pos #self._shape=None pg.ROI.__init__(self, pos, size, **kargs) def paint(self, p, *args): #pg.ROI.paint(self, p, *args) r=QtCore.QRectF(0, 0, self.state['size'][0], self.state['size'][1]).normalized() p.setRenderHint(QtGui.QPainter.Antialiasing) p.setPen(self.currentPen) p.translate(r.left(), r.top()) p.scale(r.width(), r.height()) p.drawEllipse(0, 0, 1, 1) p.drawRect(0, 0, 1, 1) p.setPen(pg.mkPen(width=3, color=[200, 100, 100])) p.drawLine(pg.Point(.5, 0), pg.Point(.5, 1)) p.drawLine(pg.Point( 0,.5), pg.Point( 1,.5)) #w, h = self.getState()["size"] #v1, v2 = -(h * 0.8) / 2, (h * 0.8) / 2 #h1, h2 = -(w * 0.8) / 2, (w * 0.8) / 2 #p.setRenderHint(QtGui.QPainter.Antialiasing) #p.setPen(pg.mkPen(width=3, color=[200, 100, 100])) #p.drawLine(pg.Point(0, v1), pg.Point(0, v2)) #p.drawLine(pg.Point(h1, 0), pg.Point(h2, 0)) #p.setPen(self.currentPen) ##p.setPen(pg.mkPen(width=3, color=[200, 200, 100])) #p.drawRect(-w / 2, -h / 2, w, h) ## p.drawText(-w, -h, '{:.0f}x{:.0f}'.format(*self._size)) ## Start Qt event loop unless running in interactive mode or using pyside. if __name__=='__main__': import sys import argparse #(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' ' #exampleCmd=('', '-m0xf -v0') epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n' parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("--mode", "-m", type=lambda x: int(x,0), help="mode default=0x%(default)x", default=0) args = parser.parse_args() pg.setConfigOptions(imageAxisOrder='row-major') def obj_info(obj): pos=obj.pos() scnPos=obj.scenePos() t=obj.transform() obj_info print(f"obj_info:{obj}") print(f"Pos:({pos.x():.6g},{pos.y():.6g})") #in coordinate value on the scene (no change by zooming) print(f"scenePos:({scnPos.x():.6g},{scnPos.y():.6g})") #in pixel on the scene (changes by zooming) print(f"QTransform:{t.m11():8.5g} {t.m12():8.5g} {t.m13():8.5g}") print(f" {t.m21():8.5g} {t.m22():8.5g} {t.m23():8.5g}") print(f" {t.m31():8.5g} {t.m32():8.5g} {t.m33():8.5g}") def pt2str(p): return (f'({p.x():.5g},{p.y():.5g})') def childTree(obj, lvl=0): print('+'*lvl+str(obj)) for child in obj.childItems(): childTree(child, lvl+1) def mouse_click_event(event): pos=event.pos() scn=event.scenePos() # there is a small black border, that makes the difference img=viImg.mapFromScene(scn) roi=viUsrRoi.mapFromScene(scn) print(f'mouse:{pt2str(pos)} {pt2str(scn)} img:{pt2str(img)} roi:{pt2str(roi)}') #childTree(vb) obj_info(viUsrRoi) ## Create image to display arr=np.ones((100, 100), dtype=float) arr[45:55, 45:55]=0 arr[25, :]=5 arr[:, 25]=5 arr[75, :]=5 arr[:, 75]=5 arr[50, :]=10 arr[:, 50]=10 arr+=np.sin(np.linspace(0, 20, 100)).reshape(1, 100) arr+=np.random.normal(size=(100, 100)) # add an arrow for asymmetry arr[10, :50]=10 arr[9:12, 44:48]=10 arr[8:13, 44:46]=10 ## create GUI app=QtGui.QApplication([]) w=pg.GraphicsLayoutWidget(show=True, size=(1000, 800), border=True) w.setWindowTitle('pyqtgraph example: ROI Examples') vb=w.addViewBox(row=1, col=0, lockAspect=True) g=pg.GridItem() vb.addItem(g) viImg=pg.ImageItem(arr, border='y') vb.addItem(viImg) # Custom ROI for selecting an image region viRoi=pg.ROI([20, 50], [100, 70]) vb.addItem(viRoi) viUsrRoi=BeamMark([10, 20], [30, 20]) vb.addItem(viUsrRoi) childTree(vb) w.scene().sigMouseClicked.connect(mouse_click_event) if (sys.flags.interactive!=1) or not hasattr(QtCore, 'PYQT_VERSION'): QtGui.QApplication.instance().exec_()