1

This question is similar to this one asked 6 years ago. However, their solution is not quite solving my problem; unlike their question, I am dealing with multiple legends, some of which are getting cut off.

I'm trying to create a figure containing multiple legends that sit outside the axes of my graph. I'm following the matplotlib documentation's instructions for creating multiple legends, using add_artist to add all but the final legend to my axes. I then use the bbox_extra_artists parameter in my savefig call as described in the above question to include all my legend objects. As seen in this example output image, the wider legend still gets cut off on the right side.

The code used to generate this plot:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = plt.gca()

for x in [0, 1, 2]:
    ax.bar(x+0.5, x+1, width=1, color=['red', 'blue', 'green'][x])

handle1 = plt.Line2D((0,1), (0,0), color='purple')
lgd1 = ax.legend([handle1], ['label1 is very long'], bbox_to_anchor=(1, 1))
ax.add_artist(lgd1)

handle2 = plt.Line2D((0,1), (0,0), color='orange')
lgd2 = ax.legend([handle2], ['label2'], bbox_to_anchor=(1, 0.9))

plt.savefig('output.png', bbox_extra_artists=(lgd1,lgd2), bbox_inches='tight')

Notably, if I change the order in which the legends are added (adding the wider legend first), the problem goes away and both legends are visible as seen here:

handle2 = plt.Line2D((0,1), (0,0), color='orange')
lgd2 = ax.legend([handle2], ['label2'], bbox_to_anchor=(1, 0.9))
ax.add_artist(lgd2)

handle1 = plt.Line2D((0,1), (0,0), color='purple')
lgd1 = ax.legend([handle1], ['label1 is very long'], bbox_to_anchor=(1, 1))

plt.savefig('output.png', bbox_extra_artists=(lgd1,lgd2), bbox_inches='tight')

For my actual project (which has to handle a dynamic number of legends), I've made it figure out which legend is "longest" and always add that legend last to work around this problem. However, this feels messy and it doesn't allow for adding more legends on other sides of the figure (e.g., I cannot add an x-axis legend below the graph without it getting cut off, since only one legend can be added "last").

Is this an intractable bug in matplotlib, or is there a tidy solution I'm missing?

Circular
  • 11
  • 2
  • Cannot reproduce with matplotlib 2.2.2. What version are you using? – DavidG May 04 '18 at 12:44
  • 2.0.0; unfortunately, updating to 2.2.2 may not be possible as my work will need to run in a shared environment where I do not control the installed libraries. – Circular May 04 '18 at 12:46
  • 1
    So that bug has been fixed in matplotlib 2.2.2, which means that the best would be to update matplotlib or ask whoever is responsible for that shared environment to update it. – ImportanceOfBeingErnest May 04 '18 at 13:10
  • I've confirmed that the problem is indeed fixed in a sandbox running 2.2.2, so I'll pursue getting matplotlib updated in the shared environment. Thank you for your help! – Circular May 04 '18 at 22:42

0 Answers0