7

I am trying to add a legend below a 3-column subplot figure.

I have tried the following:

fig, ax = plt.subplots(ncols=3)
ax[0].plot(data1)
ax[1].plot(data2)
ax[2].plot(data3)

ax_sub = plt.subplot(111)
box = ax_sub.get_position()
ax_sub.set_position([box.x0, box.y0 + box.height * 0.1,box.width, box.height * 0.9])
ax_sub.legend(['A', 'B', 'C'],loc='upper center', bbox_to_anchor=(0.5, -0.3),fancybox=False, shadow=False, ncol=3)
plt.show()

However, this creates just one empty frame. When I comment out the ax_sub part, my subplots show up nice (but without a legend...)...

Many thanks!

This is closely related to How to put the legend out of the plot

knut_h
  • 303
  • 2
  • 3
  • 11

1 Answers1

13

The legend needs to know what it should show. By default it will take the labeled artist from the axes it is created in. Since here the axes ax_sub is empty, the legend will be empty as well.

The use of the ax_sub may anyways not make too much sense. We could instead use the middle axes (ax[1]) to place the legend. However, we still need all artists that should appear in the legend. For lines this is easy; one would supply a list of lines as handles to the handles argument.

import matplotlib.pyplot as plt
import numpy as np

data1,data2,data3 = np.random.randn(3,12)

fig, ax = plt.subplots(ncols=3)
l1, = ax[0].plot(data1)
l2, = ax[1].plot(data2)
l3, = ax[2].plot(data3)

fig.subplots_adjust(bottom=0.3, wspace=0.33)

ax[1].legend(handles = [l1,l2,l3] , labels=['A', 'B', 'C'],loc='upper center', 
             bbox_to_anchor=(0.5, -0.2),fancybox=False, shadow=False, ncol=3)
plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712