6

I am making a few figures where each one has a different amount of subplots in it. I am trying to add a legend in the bottom right corner but am having some trouble. I tried adding a new subplot in the bottom right and adding a legend only to it but then had an empty subplot behind the legend. This is where I'm standing now but want the legend in the bottom right corner regardless of where the last subplot is.

fig = plt.figure()
matplotlib.rc('xtick', labelsize=8) 
matplotlib.rc('ytick', labelsize=8)

for line in a[1:]:

        ax = fig.add_subplot(subcol,subrow,counter)
        ax.plot(x,line[3:7],marker='o', color='r', label = 'oral')
        ax.plot(x,line[7:],marker='o', color='b',label = 'physa')
        ax.set_title(line[1],fontsize = 10)
        counter+=1

ax.legend(bbox_to_anchor=(2, 0),loc = 'lower right')
plt.subplots_adjust(left=0.07, right=0.93, wspace=0.25, hspace=0.35)
plt.suptitle('Kegg hedgehog',size=16)
plt.show()
Amos
  • 107
  • 1
  • 3
  • 11
  • 1
    https://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot <- I think this is a duplicate, but I am not sure and do not want to use my magic hammer just yet. – tacaswell Jun 02 '14 at 14:22
  • I have looked at this answer before and while helpful it's not exactly what I'm looking for. I tried using the answer given here but the legend I get that I try to place on the bottom of the figure is placed under the last subplot I call. So that if I have 10 subplots in a 3x4 grid the legend will be under the last subplot which will be the in the 2nd place of the bottom row, but if I have 19 subplots in a 4x5 grid the legend will be under the subplot which will be in the 4th place of the bottom row. – Amos Jun 09 '14 at 12:05
  • Reading this more carefully, your original approach is correct, just hide the frame/axis on the last subplot. – tacaswell Jun 09 '14 at 12:16
  • After trying that I got stuck with a white empty subplot on a grey background. I guess I'll start another question about how to make a clear/invisible subplot – Amos Jun 09 '14 at 13:02
  • That question has definitly been answered before – tacaswell Jun 09 '14 at 14:24
  • https://stackoverflow.com/questions/15842870/plot-nothing-but-the-legend-in-matplotlib-subplot/15843010#15843010 – tacaswell Jun 09 '14 at 14:25

2 Answers2

10

A better solution is

fig.legend(handles, labels, loc='', ...)

This adds the legend to the figure instead of the subplot.

Adapted to your example, it would be something like

fig = plt.figure()
matplotlib.rc('xtick', labelsize=8) 
matplotlib.rc('ytick', labelsize=8)

handles = []
for line in a[1:]:

        ax = fig.add_subplot(subcol,subrow,counter)
        l1 = ax.plot(x,line[3:7],marker='o', color='r', label = 'oral')
        l2 = ax.plot(x,line[7:],marker='o', color='b',label = 'physa')
        if not handles:
           handles = [l1, l2]
        ax.set_title(line[1],fontsize = 10)
        counter+=1

fig.legend(handles, ['oral', 'physa'], bbox_to_anchor=(2, 0),loc = 'lower right')
plt.subplots_adjust(left=0.07, right=0.93, wspace=0.25, hspace=0.35)
plt.suptitle('Kegg hedgehog',size=16)
plt.show()
has2k1
  • 2,095
  • 18
  • 16
  • Is there a way to get the labels/handles from one of the axes automatically? – naught101 Oct 26 '16 at 01:35
  • Ah, yes, something like `fig.legend(*g.axes[0,0].get_legend_handles_labels(), ...)` will do it. – naught101 Oct 26 '16 at 01:46
  • How do you intepret the values of the `bbox_to_anchor` argument? Thanks! – gofvonx Jan 03 '19 at 14:31
  • @gofvonx, see this [answer](https://stackoverflow.com/a/25069717/832573) and the [legend guide](https://matplotlib.org/users/legend_guide.html) and the [documentation](https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.legend.html). – has2k1 Jan 04 '19 at 14:01
2

I ended up adding an extra subplot which I removed the frame and axis of, then plotted nothing to it and added a legend

lastSubplot = plt.subplot(subcol,subrow,subcol*subrow)
lastSubplot.set_frame_on(False)
lastSubplot.get_xaxis().set_visible(False)
lastSubplot.get_yaxis().set_visible(False)
plt.plot(0, 0, marker='o', color='r', label = 'line1')
plt.plot(0, 0, marker='o', color='b', label = 'line2')
lastSubplot.legend(loc = 'lower right')

This left me with only the legend in the bottom right corner regardless of how many subplots I actually had.

Amos
  • 107
  • 1
  • 3
  • 11