connect='finite' within the same plot item to make it much faster.However, now I can't give a separate ID to each boundary. I have to make the vertices stand out, and connect to sigclicked(...pts) instead:
This works, but I'd love to be able to click anywhere on one of the line segments for the same effect. Is there any way to make this happen?
Relevant code is just a PlotDataItem on a plot widget.
Thanks!import pyqtgraph as pg
import numpy as np
tri = np.array([[0,0], [0,5], [5,5], [0,0]])
nans = np.array([[np.nan, np.nan]])
tris = []
datas = []
for ii in np.arange(0, 16, 5):
tris.append(tri + ii)
tris.append(nans)
datas.extend([ii]*5) # One data for each point
tris = np.vstack(tris)
datas = np.array(datas)
def ptsClicked(item, pts):
print(f'ID {pts[0].data()} Clicked!')
app = pg.mkQApp()
triItem = pg.PlotDataItem(x=tris[:,0], y=tris[:,1], data=datas, symbol='o')
triItem.sigPointsClicked.connect(ptsClicked)
w = pg.PlotWindow()
w.plotItem.addItem(triItem)
w.show()
app.exec()
--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/fb10aa48-efe9-40f9-ae3e-553c1998d8e0o%40googlegroups.com.
import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, QtCore, QtGui
import numpy as np
tri = np.array([[0,0], [0,5], [5,5], [0,0]])
tris = []
xyLocs = []
datas = []
for ii in np.arange(0, 16, 5):
curTri = tri + ii
tris.append(curTri)
xyLocs.append(curTri.min(0))
datas.append(ii)
def ptsClicked(item, pts):
print(f'ID {pts[0].data()} Clicked!')
def makeSymbol(verts: np.ndarray):
outSymbol = QtGui.QPainterPath()
symPath = pg.arrayToQPath(*verts.T)
outSymbol.addPath(symPath)
# From pyqtgraph.examples for plotting text
br = outSymbol.boundingRect()
tr = QtGui.QTransform()
tr.scale(1/br.width(), 1/br.height())
tr.translate(-br.x() - br.width()/2., -br.y() - br.height()/2.)
outSymbol = tr.map(outSymbol)
return outSymbol
app = pg.mkQApp()
symbs = []
for xyLoc, tri in zip(xyLocs, tris):
symbs.append(makeSymbol(tri))
xyLocs = np.vstack(xyLocs)
tri2 = pg.PlotDataItem(*xyLocs.T, symbol=symbs, data=datas, connect='finite',
pen=None)
# Now each 'point' is one of the triangles, hopefully
tri2.sigPointsClicked.connect(ptsClicked)
w = pg.PlotWindow()
w.plotItem.addItem(tri2)
w.show()
app.exec()
Enter code here...--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/3199cb82-a432-4434-aed4-c716fbcd932eo%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqt...@googlegroups.com.
import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, QtCore, QtGui
import numpy as np
class CustScatter(pg.ScatterPlotItem):
def pointsAt(self, pos: QtCore.QPointF):
# if isinstance(pos, QtCore.QPointF):
# halfSz = 0.25
# pos = QtCore.QRectF(pos.x()-halfSz, pos.y()-halfSz, 2*halfSz, 2*halfSz)
pts = []
for spot in self.points(): # type: pg.SpotItem
symb = QtGui.QPainterPath(spot.symbol())
symb.translate(spot.pos())
stroker = QtGui.QPainterPathStroker()
mousePath = stroker.createStroke(symb)
if mousePath.contains(pos):
pts.append(spot)
return pts[::-1]
tri = np.array([[0,2.3,0,1,4,5,0], [0,4,4,8,8,3,0]]).T
tris = []
xyLocs = []
datas = []
for ii in np.arange(0, 16, 5):
curTri = tri + ii
tris.append(curTri)
xyLocs.append(curTri.min(0))
datas.append(ii)
def ptsClicked(item, pts):
print(f'ID {pts[0].data()} Clicked!')
def makeSymbol(verts: np.ndarray):
outSymbol = QtGui.QPainterPath()
symPath = pg.arrayToQPath(*verts.T)
outSymbol.addPath(symPath)
# From pyqtgraph.examples for plotting text
br = outSymbol.boundingRect()
tr = QtGui.QTransform()
tr.translate(-br.x(), -br.y())
outSymbol = tr.map(outSymbol)
return outSymbol
app = pg.mkQApp()
pg.setConfigOption('background', 'w')
symbs = []
for xyLoc, tri in zip(xyLocs, tris):
symbs.append(makeSymbol(tri))
xyLocs = np.vstack(xyLocs)
tri2 = pg.PlotDataItem()
scat = CustScatter(*xyLocs.T, symbol=symbs, data=datas, connect='finite',
pxMode=False, brush=None, pen=pg.mkPen(width=5), size=1)
scat.sigClicked.connect(ptsClicked)
# Now each 'point' is one of the triangles, hopefully
w = pg.PlotWindow()
w.plotItem.addItem(scat)
plt: pg.PlotItem = w.plotItem
plt.showGrid(True, True, 1)
w.show()
app.exec()
class CustScatter(pg.ScatterPlotItem):
def pointsAt(self, pos: QtCore.QPointF):
"""
The default implementation only checks a square around each spot. However, this is not
precise enough for my needs. It also triggers when clicking *inside* the spot boundary,
which I don't want.
"""
pts = []
for spot in self.points(): # type: pg.SpotItem
symb = QtGui.QPainterPath(spot.symbol())
symb.translate(spot.pos())
stroker = QtGui.QPainterPathStroker()
mousePath = stroker.createStroke(symb)
# Only trigger when clicking a boundary, not the inside of the shape
if mousePath.contains(pos):
pts.append(spot)
return pts[::-1]
def measureSpotSizes(self, dataSet):
for rec in dataSet:
## keep track of the maximum spot size and pixel size
symbol, size, pen, brush = self.getSpotOpts(rec)
br = symbol.boundingRect()
size = max(br.width(), br.height())*2
width = 0
pxWidth = 0
if self.opts['pxMode']:
pxWidth = size + pen.widthF()
else:
width = size
if pen.isCosmetic():
pxWidth += pen.widthF()
else:
width += pen.widthF()
self._maxSpotWidth = max(self._maxSpotWidth, width)
self._maxSpotPxWidth = max(self._maxSpotPxWidth, pxWidth)
self.bounds = [None, None]Enter code here...