niboshi niboshi - 6 months ago 274
Python Question

Matplotlib savefig with a legend outside the plot

Reading the following article, I managed to put a legend outside plot.



code:

import matplotlib.pyplot as pyplot

x = [0, 1, 2, 3, 4]
y = [xx*xx for xx in x]

fig = pyplot.figure()
ax = fig.add_subplot(111)

box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width*0.8, box.height])

ax.plot(x, y)
leg = ax.legend(['abc'], loc = 'center left', bbox_to_anchor = (1.0, 0.5))
#pyplot.show()

fig.savefig('aaa.png', bbox_inches='tight')


pyplot.show()
displays the correct plot with a legend outside it. But when I save it as a file with
fig.savefig()
, the legend is truncated.

Some googling shows me workarounds such as adding
bbox_extra_artists=[leg.legendPatch]
or
bbox_extra_artists=[leg]
to
savefig()
, but neither worked.

What is the correct way to do it? Matplotlib version is 0.99.3.

Thanks.

Answer

The problem is that when you plot dinamically, matplotlib determines the borders automatically to fit all your objects. When you save a file, things are not being done automagically, so you need to specify the size of your figure, and then the bounding box of your axes object. Here is how to correct your code:

import matplotlib.pyplot as pyplot

x = [0, 1, 2, 3, 4]
y = [xx*xx for xx in x]

fig = pyplot.figure(figsize=(3,3))
ax  = fig.add_subplot(111)

#box = ax.get_position()
#ax.set_position([0.3, 0.4, box.width*0.3, box.height])
# you can set the position manually, with setting left,buttom, witdh, hight of the axis
# object
ax.set_position([0.1,0.1,0.5,0.8])
ax.plot(x, y)
leg = ax.legend(['abc'], loc = 'center left', bbox_to_anchor = (1.0, 0.5))

fig.savefig('aaa.png')