pythonpyqtgraph

pyqtgraph: LegendItem offset returns false values regardless of position


I have a Qt5 window with a pyqtgraph in a dynamic situation, i.e., plots, axes, curves can be added or modified. Also, the legend can be shown and hidden. Since the user can also drag the legend to a different place using the mouse, I would like to store its position and perhaps restore this position later. Setting a position using LegendItems' setOffset works as expected, but regardless of the actual position, LegendItems' offset attribute always returns the same values. Here's a MWE:

import numpy as np
import pyqtgraph as pg

win = pg.plot()
win.setWindowTitle('MWE legend offset')

c1 = win.plot([np.random.randint(0,8) for i in range(10)], pen='r', name='curve1')

legend = pg.LegendItem((80,60), offset=(70,20))
legend.setParentItem(win.graphicsItem())
legend.addItem(c1, 'curve1')

print(f"Before setting an offset: {legend.offset}") # Gives (70,20)
legend.setOffset([300,300])
print(f"After setting an offset: {legend.offset}") # Gives (70,20) as well

if __name__ == '__main__':
    pg.exec()

Any idea how to get the real LegendItem position?

EDIT: The suggested legend.opts['offset'] seems to work if the offset is set via legend.setOffset([300,300]), as suggested by Rik.

However, my use case is a bit different: The legend can be moved by a mouse drag, but this does not seem to affect the offset. According to the source code of LegendItem, the mouseDragEvent modifies the autoAnchor which is a GraphicsWidgetAnchor object. So far, I am stuck here of how to obtain its values. (An option I see is subclassing LegendItem and overwrite the mouseDragEvent, but I was wondering if that is necessary..)


Solution

  • Replacing legend.offset by legend.pos() does work.

    edit 1: The mistake that the devs made is that legend has a method legend.offset() and a property legend.offset. This property overwrites the correct method, and is itself never actually updated, so is incorrect. When you call legend.offset() you get an error, since you then call the property legend.offset, which is not a function. I have sent a pull request to the source code to fix this.

    edit 2: legend.pos() (instead of my previous answer legend.opts['offset']) seems to always work. I now do not understand why offset exists, as it seems to be a copy of pos() except that it is sometimes wrong.