Common xlabel/ylabel for matplotlib subplots
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Techno Intrigue Looping
--
Chapters
00:00 Common Xlabel/Ylabel For Matplotlib Subplots
00:49 Accepted Answer Score 337
01:16 Answer 2 Score 174
01:55 Answer 3 Score 165
02:36 Answer 4 Score 46
03:05 Answer 5 Score 18
03:50 Thank you
--
Full question
https://stackoverflow.com/questions/1615...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #matplotlib
#avk47
ACCEPTED ANSWER
Score 344
This looks like what you actually want. It applies the same approach of this answer to your specific case:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True, figsize=(6, 6))
fig.text(0.5, 0.04, 'common X', ha='center')
fig.text(0.04, 0.5, 'common Y', va='center', rotation='vertical')

ANSWER 2
Score 176
Since I consider it relevant and elegant enough (no need to specify coordinates to place text), I copy (with a slight adaptation) an answer to another related question.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, sharex=True, sharey=True, figsize=(6,15))
# add a big axis, hide frame
fig.add_subplot(111, frameon=False)
# hide tick and tick label of the big axis
plt.tick_params(labelcolor='none', which='both', top=False, bottom=False, left=False, right=False)
plt.xlabel("common X")
plt.ylabel("common Y")
This results in the following (with matplotlib version 2.2.0):
ANSWER 3
Score 46
Without sharex=True, sharey=True you get:

With it you should get it nicer:
fig, axes2d = plt.subplots(nrows=3, ncols=3,
sharex=True, sharey=True,
figsize=(6,6))
for i, row in enumerate(axes2d):
for j, cell in enumerate(row):
cell.imshow(np.random.rand(32,32))
plt.tight_layout()

But if you want to add additional labels, you should add them only to the edge plots:
fig, axes2d = plt.subplots(nrows=3, ncols=3,
sharex=True, sharey=True,
figsize=(6,6))
for i, row in enumerate(axes2d):
for j, cell in enumerate(row):
cell.imshow(np.random.rand(32,32))
if i == len(axes2d) - 1:
cell.set_xlabel("noise column: {0:d}".format(j + 1))
if j == 0:
cell.set_ylabel("noise row: {0:d}".format(i + 1))
plt.tight_layout()

Adding label for each plot would spoil it (maybe there is a way to automatically detect repeated labels, but I am not aware of one).
ANSWER 4
Score 19
Since the command:
fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)
you used returns a tuple consisting of the figure and a list of the axes instances, it is already sufficient to do something like (mind that I've changed fig,axto fig,axes):
fig,axes = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)
for ax in axes:
ax.set_xlabel('Common x-label')
ax.set_ylabel('Common y-label')
If you happen to want to change some details on a specific subplot, you can access it via axes[i] where i iterates over your subplots.
It might also be very helpful to include a
fig.tight_layout()
at the end of the file, before the plt.show(), in order to avoid overlapping labels.
