0

This is what it looks when you add pg.TextItems to each individual pg.ScatterPlotItem

enter image description here

using:

label = pg.TextItem(text=str(i), color=HEX_ORANGE, anchor=([1, 1]))
label.setPos(x, y)
self.plot.addItem(label)

but this can only be done in a for loop and that is slow... so i wanted to replace it with a faster solution. I found that replacing it with QPainterPath works for pg.ScatterPlotItem but i cannot get them to behave the same using:

from PySide6.QtGui import QTransform, QPainterPath, QFont


def genSymbol(label):
    # Basically the example in pyqtgraph/examples/ScatterPlotItem
    symbol = QPainterPath()
    f = QFont()
    f.setPointSize(5)
    symbol.addText(0, 0, f, label)
    br = symbol.boundingRect()
    scale = min(1. / br.width(), 1. / br.height())
    tr = QTransform()
    tr.scale(scale, scale)
    tr.translate(-br.x() - br.width()/2., -br.y() - br.height()/2.)
    return symbol


if __name__ == '__main__':

    import pyqtgraph as pg
    from PySide6.QtWidgets import QMainWindow
    from PySide6.QtGui import QColor

    app = pg.mkQApp("PerPlotHelper")
    w = QMainWindow()
    cw = pg.GraphicsLayoutWidget()
    w.show()
    w.resize(600, 600)
    w.setCentralWidget(cw)
    w.setWindowTitle('pyqtgraph example: Arrow')
    p = cw.addPlot(row=0, col=0)
    ####
    point_xs = [1, 2, 3, 4, 5, 6]
    point_ys = [1, 2, 3, 4, 5, 6]

    points = pg.ScatterPlotItem(point_xs, point_ys,
                                symbol='o',
                                size=9,
                                pen=pg.mkPen(QColor("#ff9900")),
                                brush=pg.mkBrush(QColor("#ff9900")),
                                data="w/e")
    p.addItem(points)
    symbols = [genSymbol(str(i)) for i in range(len(point_xs))]
    # Draw Text Label
    spots = [{'x': point_xs[i],
              'y': point_ys[i],
              'data': "w/e",
              'brush': "#ff9900",
              'symbol': symbols[i]} for i in range(len(point_xs))]
    textLabelsP = pg.ScatterPlotItem(pen=pg.mkPen('w'), pxMode=True)
    textLabelsP.addPoints(spots)
    p.addItem(textLabelsP)

    app.exec()

only puts small, barely visible text on the top-right inside the point itself...

enter image description here

or with pxMode=False it produces this abomination:

enter image description here

What am i missing?

Thanks.

Andrei M.
  • 313
  • 2
  • 10

1 Answers1

0

A symbol of the ScatterPlotItem is designed to be clipped by a rectangle of (x=-0.5, y=-0.5, width=1, height=1), where (x=0, y=0) means the center of the corresponding data point and the coordinates are scaled by the size option.

For your toy example, you can do like this, although it's useless.

...
def genSymbol(label):
    symbol = QPainterPath()
    f = QFont()
    f.setPixelSize(1)
    symbol.addText(-0.5, 0.5, f, label)
    return symbol
...
if ...
    ...
    spots = [{'x': point_xs[i],
              'y': point_ys[i],
              'size': 10, # The default value is 7 but it's too small.
              'data': "w/e",
              'brush': "#ff9900",
              'symbol': symbols[i]} for i in range(len(point_xs))]
    ...
...
relent95
  • 3,703
  • 1
  • 14
  • 17