Constrained layout collapses legend outside of plot

Hello eveyrone,

I have 3 subplots using gridspec + constrained layout and I want to put a uniform legend above them so I use the following code:

axs[0].legend(
loc=3,  
bbox_to_anchor=(0.0, 1.02, 1.8, 0.05), 
ncol=2, 
boarderaxespad=0.0, 
mode="expand",
framon=False
)

but I get the following result:

Any ideas on why this happens and what I should do? Thank you in advance!

constrained_layout makes the space between axes large enough to accommodate all decorations. You have added a very wide decoration to axs[0] so it is allocated lots of space. You can take the legend out of the layout using leg.set_in_layout(False), or you can make the legend a figure legend instead of an axes legend. However, be aware that neither method will give you a nice space at the top for your legend. There is a PR for this, but was bogged down in API discussions. ENH: allow fig.legend outside axes... by jklymak · Pull Request #19743 · matplotlib/matplotlib · GitHub

Yeah I understand. The weird thing is that I had made similar plots and it worked but I was playing with the size of the legend sometimes it collapsed sometimes it didn’t. It’s weird also that it allocates a lot of space for axs[0] but legend still remains collapsed.
Can I make an empty axes on top of the 3 subplots and put there my legend while respecting the gridspec and the constrained layout?

Yes, that is a good solution. Maybe use subplot_mosaic:

fig, axs = plt.subplot_mosaic([['leg', 'leg', 'leg']['l', 'c', 'r']], gridspec_kw={'height_ratios': [0.2, 1]})

where you could tweak the height ratios to suit the size you need to leave for the legend. axs['leg'].legend would then work.

Perfect thanks it seems to be working!

I created an empty subplot that extends the full width on top of my 3 main ones and used

axs[1].get_legend_handles_labels()

to take the legend from the subplot with the lines
and to put it in the empty one

axs[0].legend(handles, labels, **legend_kwargs)

for anyone who might be interested.

2 Likes