Consider the following example:
import matplotlib.pyplot as plt
from matplotlib import gridspec
import numpy as np
x = np.linspace(0, 10, 100)
y = 2*x + 0.5
plt.figure(figsize=(6, 4))
gs = gridspec.GridSpec(2, 2)
plt.subplot(gs[0, 0])
plt.plot(x, y, "o")
plt.subplot(gs[0, 1])
plt.plot(x, y, "o")
plt.subplot(gs[1, :])
plt.plot(x, y, "o", label="test")
plt.legend(loc="upper center", bbox_to_anchor=(0.5, 2.7))
plt.subplot(gs[2, :])
plt.plot(x, y, "o")
plt.tight_layout()
plt.show()
When I remove bbox_to_anchor
from plt.legend
, the above code should produce something like this:
But when I place the legend outside of the subplot using bbox_to_anchor
(as in the code above), the subplots get squashed:
Obviously, this is not desired. There seems to be a conflict between bbox_to_anchor
and tight_layout()
(if you remove either from the code above, something sensible comes out). Is there something I'm doing wrong, or is this known/expected behaviour?
This problem is reproduced under various back-ends. I don't get any warnings or errors. I'm using matplotlib version 2.2.2
.
The result is expected, although clearly not desireable. Since the legend is part of the lower subplot, it will take part in the tight_layout
mechanism and hence shift everything to the top.
You may call tight_layout
first,
plt.tight_layout()
plt.legend(loc="upper center", bbox_to_anchor=(0.5, 2.3))
to get the tight spacing and then afterwards create the legend.
You may also create a figure legend,
fig = plt.figure(figsize=(6, 4))
# ...
fig.legend(loc="upper center", bbox_to_anchor=(0.5, .9))
plt.tight_layout()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With