2

I'm trying to get and set the position of a draggable legend in matplotlib. My application consists of an interactive GUI, which has a redraw/plot function that should perform the follow steps:

  1. save the position of the current legend.
  2. clear the current axes and perform various plotting operations, which may or may add labels to their plots.
  3. build a new draggable legend (ax.legend().draggable()) and restore the old position of the legend.

In between these steps the user is free to drag the legend around, and the goal is to persist the legend position when the plots are redrawn.

My first approach was to use oldpos = legend.get_bbox_to_anchor() and legend.set_bbox_to_anchor(oldpos) in steps 1 and 3. However this causes to move the legend completely off the visible area.

Note that I have to use ax.legend() and cannot use fig.legend(lines, labels), since step 2 is completely decoupled, i.e., I don't know anything about lines and labels in step 3. According to answers to the question How to position and align a matplotlib figure legend? there seems to be a difference between these two possibilities regarding axes or figure coordinates. Obviously my problem calls for figure coordinates, but I haven't fully understood how to convert the bbox to a "bbox in figure coordinates".

The even more severe problem I just realized is that apparently legend.get_bbox_to_anchor() always seems to return the same values irrespective of the drag position. So maybe the anchor can only be (ab-)used to manipulate the position of static legends? Is there another/proper way to save and restore the position of a draggable legend?

Community
  • 1
  • 1
bluenote10
  • 23,414
  • 14
  • 122
  • 178

1 Answers1

2

By looking at the implementation of Legend I found out that there is an undocumented property _loc, which exactly does what I want. My solution now looks astonishingly simple:

oldLegPos = ax.get_legend()._loc

# perform all plotting operations...

legend = ax.legend().draggable()
legend._loc = oldLegPos

It looks like _loc automatically stores figure coordinates, since I do not have to convert the coordinates in any way (eg. when the plotting operations completely change the axes ranges/coordinates).

bluenote10
  • 23,414
  • 14
  • 122
  • 178