user1716021
user1716021

Reputation: 51

How do I draw a rectangle on the legend in matplotlib?

I am trying to plot a rectangle onto the legend in matplotlib.

To illustrate how far I have gotten I show my best attempt, which does NOT work:

import matplotlib.pyplot as plt  
from matplotlib.patches import Rectangle
import numpy as np

Fig = plt.figure()
ax = plt.subplot(111)

t = np.arange(0.01, 10.0, 0.01)
s1 = np.exp(t)
ax.plot(t, s1, 'b-', label = 'dots')

leg = ax.legend()

rectangle = Rectangle((leg.get_frame().get_x(),
                  leg.get_frame().get_y()),
                  leg.get_frame().get_width(),
                  leg.get_frame().get_height(), 
                  fc = 'red'
                 )

ax.add_patch(rectangle)

plt.show()

The rectangle just isn't draw anywhere in the figure. If I look at the values of leg.get_frame().get_x(), leg.get_frame().get_y()), leg.get_frame().get_width() and leg.get_frame().get_height(), I see that they are 0.0, 0.0, 1.0 and 1.0 respectively.

My problem thus sees to be, to find the co-ordinates of the frame of the legend.

It would be really great if you could help me out.

Thanks for reading this far.

Upvotes: 5

Views: 7564

Answers (2)

Naffi
Naffi

Reputation: 730

This link may have the exact thing you are looking for. http://matplotlib.org/users/legend_guide.html#creating-artists-specifically-for-adding-to-the-legend-aka-proxy-artists

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

red_patch = mpatches.Patch(color='red', label='The red data')
plt.legend(handles=[red_patch])

plt.show()

Upvotes: 4

user707650
user707650

Reputation:

The trouble is that the position of the legend is not known in advance. Only by the time you render the figure (calling plot()), is the position decided.

A solution I came across is to draw the figure twice. In addition, I've used axes coordinates (default is data coordinates) and scaled the rectangle so you still see a bit of the legend behind it. Note that I had to set the legend and rectangle zorder as well; the legend gets drawn later than the rectangle and thus the rectangle otherwise disappears behind the legend.

import numpy as np
import matplotlib.pyplot as plt  
from matplotlib.patches import Rectangle

Fig = plt.figure()
ax = plt.subplot(111)

t = np.arange(0.01, 10.0, 0.01)
s1 = np.exp(t)
ax.plot(t, s1, 'b-', label = 'dots')

leg = ax.legend()
leg.set_zorder(1)
plt.draw()  # legend position is now known
bbox = leg.legendPatch.get_bbox().inverse_transformed(ax.transAxes)
rectangle = Rectangle((bbox.x0, bbox.y0), 
                      bbox.width*0.8, bbox.height*0.8, 
                      fc='red', transform=ax.transAxes, zorder=2)
ax.add_patch(rectangle)
plt.show()

Upvotes: 2

Related Questions