7

I would like a TextItem that maintains a constant position on the graph while scaling the y-axis, essentially the same functionality as legend only as a TextItem where I can change the text as needed. I cannot figure out how to do this. Any suggestions welcome.

This example shows the problem. On the lefthand graph, scaling the y-axis causes the text to move whereas on the righthand graph the legend stays in a constant position as you scale. I would like the position of the textItem to be defined like the legend position, in a constant position relative to the graph window. Alternatively if someone knows how to change the format of the legend and update the text that would also work, but from my reading of the documentation this is not possible.

import pyqtgraph as pg 
from PyQt4 import QtGui 
import numpy as np 
import sys 
def main(): 
    app = QtGui.QApplication(sys.argv) 
    widg = QtGui.QWidget() 
    widg.move(100, 100) 
    pg.setConfigOption('background', 'w')
    pg.setConfigOption('foreground', 'k') 

    pgWidg = pg.GraphicsLayoutWidget()   
    pgWidg.resize(750, 250)  

    graph1 = pgWidg.addPlot(row=1, col=1) 
    graph2 = pgWidg.addPlot(row=1, col=2)
    curve1 = graph1.plot(y=np.sin(np.linspace(1, 21, 1000)), pen='k') 
    curve2 = graph2.plot(y=np.sin(np.linspace(1, 21, 1000)), pen='k') 

    graph1.addItem(curve1) 
    graph2.addItem(curve2) 
    graph1.setMouseEnabled(x=False, y=True)
    graph2.setMouseEnabled(x=False, y=True)

    graph1Text = pg.TextItem(text = 'A1', color=(0, 0, 0))
    graph1.addItem(graph1Text)
    graph1Text.setPos(150, 1)

    legend = graph2.addLegend()
    style = pg.PlotDataItem(pen='w')
    legend.addItem(style, 'A2')

    grid = QtGui.QGridLayout() 
    grid.addWidget(pgWidg, 0,0)          
    widg.setLayout(grid) 
    widg.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
user3276846
  • 93
  • 1
  • 5

3 Answers3

2

7 bilion years later of googling...

        label = pg.LabelItem("Error", size="36pt", color="FF0000")
        label.setParentItem(self.plotInstance)
        label.anchor(itemPos=(1,0), parentPos=(1,0), offset=(-10,10))

where self.plotInstance = pg.PlotWidget.getPlotItem()

works on PyQt5 and pyqtgraph 0.12

Andrei M.
  • 313
  • 2
  • 10
1

This is a somewhat old question now- Hopefully this will help someone. Answering this helped me answer my own question.

Please note that I used PySide2 rather than PyQt4- I don't think this is significantly different to PyQt4. I am also using pyqtgraph 0.11.1.

There is a getLabel() method of the LegendItem that returns the LabelItem inside the legend for a given plotItem. This should allow you to do what you want.

You created your legend with this code:

legend = graph2.addLegend()
style = pg.PlotDataItem(pen='w')
legend.addItem(style, 'A2')

You can then get the labelitem with:

legend_labelitem = legend.getLabel(style)

With that you should be able to change the properties - such as using .setText() to set a new legend text:

legend_labelitem.setText('Something else')

The full code would end up as this:

import pyqtgraph as pg 
# from PySide2 import QtGui  # <---- tested with this
from PyQt4 import QtGui 
import numpy as np 
import sys 
def main(): 
    app = QtGui.QApplication(sys.argv) 
    widg = QtGui.QWidget() 
    widg.move(100, 100) 
    pg.setConfigOption('background', 'w')
    pg.setConfigOption('foreground', 'k') 

    pgWidg = pg.GraphicsLayoutWidget()   
    pgWidg.resize(750, 250)  

    graph1 = pgWidg.addPlot(row=1, col=1) 
    graph2 = pgWidg.addPlot(row=1, col=2)
    curve1 = graph1.plot(y=np.sin(np.linspace(1, 21, 1000)), pen='k') 
    curve2 = graph2.plot(y=np.sin(np.linspace(1, 21, 1000)), pen='k') 

    graph1.addItem(curve1) 
    graph2.addItem(curve2) 
    graph1.setMouseEnabled(x=False, y=True)
    graph2.setMouseEnabled(x=False, y=True)

    graph1Text = pg.TextItem(text = 'A1', color=(0, 0, 0))
    graph1.addItem(graph1Text)
    graph1Text.setPos(150, 1)

    legend = graph2.addLegend()
    style = pg.PlotDataItem(pen='w')
    legend.addItem(style, 'A2')
    legend_labelitem = legend.getLabel(style)  # <---------
    legend_labelitem.setText('Something else')  # <---------

    grid = QtGui.QGridLayout() 
    grid.addWidget(pgWidg, 0,0)          
    widg.setLayout(grid) 
    widg.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main()

It produces this:

changed legend text

Oli N
  • 59
  • 1
  • 5
0

A bit late, but you can make this happen easily by defining a text item that ignores item transforms. It is important that you use setParentItem with this, similar to how you would with a legend item:

import pyqtgraph as pg

pg.mkQApp()

plot = pg.PlotWidget()
moving_item = pg.TextItem("Moving", anchor=(0.5, 0.5))
still_item = pg.TextItem("Still", anchor=(0.5, 0.5))

still_item.setFlag(still_item.GraphicsItemFlag.ItemIgnoresTransformations)
# ^^^ This line is necessary

plot.addItem(moving_item, ignoreBounds=True)
# Use this instead of `plot.addItem`
still_item.setParentItem(plot.plotItem)

# This position will be in pixels, not scene coordinates since transforms are ignored.
# You can use helpers like `mapFromScene()` etc. to translate between pixels
# and viewbox coordinates
still_item.setPos(300, 300)

plot.show()

pg.exec()

1

ntjess
  • 570
  • 6
  • 10