jhaiduce
jhaiduce

Reputation: 438

How to get legend location in matplotlib

I'm trying to get the legend location in matplotlib. It seems like Legend.get_window_extent() should provide this, but it returns the same value regardless of where the legend is located. Here is an example:

from matplotlib import pyplot as plt

def get_legend_pos(loc):

    plt.figure()
    plt.plot([0,1],label='Plot')
    legend=plt.legend(loc=loc)

    plt.draw()

    return legend.get_window_extent()

if __name__=='__main__':

    # Returns a bbox that goes from (0,0) to (1,1)
    print get_legend_pos('upper left')

    # Returns the same bbox, even though legend is in a different location!
    print get_legend_pos('upper right')

What is the correct way to get the legend location?

Upvotes: 3

Views: 2752

Answers (2)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339092

You would need to replace plt.draw() by

plt.gcf().canvas.draw()

or, if you have a figure handle, fig.canvas.draw(). This is needed because the legend position is only determined when the canvas is drawn, beforehands it just sits in the same place.

Using plt.draw() is not sufficient, because the drawing the legend requires a valid renderer from the backend in use.

Upvotes: 3

matusko
matusko

Reputation: 3767

TL DR; Try this:

def get_legend_pos(loc):
    plt.figure()
    plt.plot([0,1],label='Plot')
    legend=plt.legend(loc=loc)
    plt.draw()
    plt.pause(0.0001)
    return legend.get_window_extent()

Here is why

So I tried your code in Jupyter and I can reproduce the behavior with option

%matplotlib notebook

However for

%matplotlib inline

I am getting correct response

Bbox(x0=60.0, y0=230.6, x1=125.69999999999999, y1=253.2)
Bbox(x0=317.1, y0=230.6, x1=382.8, y1=253.2)

It looks like in the first case the legend position is not evaluated until the execution finishes. Here is an example that proves it, in the first cell I execute

fig = plt.figure()
plt.plot([0,1],label='Plot')
legend=plt.legend(loc='upper left')
plt.draw()
print(legend.get_window_extent()) 

Outputs Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0).

In the next cell re-evaluate the last expression

print(legend.get_window_extent()) 

Outputs Bbox(x0=88.0, y0=396.2, x1=175.725, y1=424.0)

You probably just need to add plt.pause() to enforce the evaluation.

Upvotes: 2

Related Questions