Using PyQt5 and PyQtGraph, I have a circular Scatter Plot displayed on top of an image. Both these items are inside a QGraphicsView, which was promoted from an ImageView object. I am trying to find an easy way of mass-selecting specific points when there could be potentially hundreds generated.
I discovered a CircleROI object that subclasses pyqtgraph's ROI. After creating the circle, I'd like to have some way to reference the points "selected" inside it...from there data export is simple. But I don't know how to make that work.
Here is what I am trying at the moment:
self.roi = pg.CircleROI([500, 500], [100, 100], pen=(4,9), movable=True, resizable=True)
self.roi.setAcceptedMouseButtons(QtCore.Qt.MouseButton.RightButton)
self.roi.sigClicked.connect(self.select_points)
self.graphicsView.view.addItem(self.roi)
def select_points(self):
#self.dataPlot is a pg.ScatterPlotItem
selected = self.roi.getArrayRegion(self.dataPlot.points, self.graphicsView.imageItem, axes=(0))
print(*selected, sep = ", ")
I am getting this error:
selected = self.roi.getArrayRegion(self.dataPlot.points, self.graphicsView.imageItem, axes=(0))
File "C:\runnable\soft\Python37\lib\site-packages\pyqtgraph\graphicsItems\ROI.py", line 1891, in getArrayRegion
returnMappedCoords, **kwds)
File "C:\runnable\soft\Python37\lib\site-packages\pyqtgraph\graphicsItems\ROI.py", line 1193, in getArrayRegion
rgn = fn.affineSlice(data, shape=shape, vectors=vectors, origin=origin, axes=axes, **kwds)
File "C:\runnable\soft\Python37\lib\site-packages\pyqtgraph\functions.py", line 810, in affineSlice
x = affineSliceCoords(shape, origin, vectors, axes)
File "C:\runnable\soft\Python37\lib\site-packages\pyqtgraph\functions.py", line 740, in affineSliceCoords
if len(origin) != len(axes):
TypeError: object of type 'int' has no len()
How can I fix this error? If this is the wrong approach, what would I do instead?
I actually found the answer a while ago but forgot to update. I had to get a little creative to get exactly what I wanted.
The first step is of course to make the actual ROI object, and add it to the graphics view:
self.roi = pg.CircleROI([110, 50], [20, 20], pen=(4,9))
self.graphicsView.view.addItem(self.roi)
Then use the ROI's geometry to determine what spots on the graph it is colliding with. I had to use mapRectToItem to have the roi's bounding rect be in the same coordinate space as the data plot:
roiHitbox = self.roi.mapRectToItem(self.dataPlot, self.roi.boundingRect())
points = self.dataPlot.points()
collidedPoints = []
for p in points:
#p.viewPos() is a QPointF.
if(roiHitbox.contains(p.viewPos())):
collidedPoints.append(p)
newList = set(collidedPoints)