The Python Oracle

Common xlabel/ylabel for matplotlib subplots

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Quiet Intelligence

--

Chapters
00:00 Question
00:45 Accepted answer (Score 318)
01:14 Answer 2 (Score 153)
01:56 Answer 3 (Score 124)
02:48 Answer 4 (Score 43)
03:52 Thank you

--

Full question
https://stackoverflow.com/questions/1615...

Accepted answer links:
[this answer]: https://stackoverflow.com/a/6981055/3753...

Answer 2 links:
[an answer to another related question]: https://stackoverflow.com/a/36542971/187...
[image]: https://i.stack.imgur.com/noSEfl.png

Answer 3 links:
[image]: https://i.stack.imgur.com/zl7zm.png
[image]: https://i.stack.imgur.com/alQYK.png
[image]: https://i.stack.imgur.com/3qV0x.png
[see more]: https://matplotlib.org/stable/gallery/su...

--

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')

Multiple plots with common axes label




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):

5 rows and 2 columns subplots with common x and y axis labels




ANSWER 3

Score 46


Without sharex=True, sharey=True you get:

enter image description here

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()

enter image description here

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()

enter image description here

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.