233 votes

xlabel/ylabel commun pour les sous-plans de matplotlib

J'ai la parcelle suivante :

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

et j'aimerais maintenant donner à ce graphique des étiquettes communes pour l'axe des x et l'axe des y. Par "commun", j'entends qu'il devrait y avoir une grande étiquette d'axe des x sous toute la grille des sous-plans, et une grande étiquette d'axe des y à droite. Je ne trouve rien à ce sujet dans la documentation de plt.subplots et mes recherches sur Google suggèrent que je dois faire un gros plt.subplot(111) pour commencer - mais comment puis-je ensuite y placer mes 5*2 sous-intrigues en utilisant plt.subplots ?

300voto

divenex Points 5192

Ça ressemble à ce que vous voulez vraiment. Il applique la même approche de cette réponse à votre cas spécifique :

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

132voto

bli Points 2369

Puisque je considère que c'est suffisamment pertinent et élégant (pas besoin de préciser les coordonnées pour placer le texte), je copie (avec une légère adaptation) une réponse à une autre question connexe .

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

Le résultat est le suivant (avec matplotlib version 2.2.0) :

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

91voto

Oren Points 1045

Nouveautés de Matplotlib v3.4 ( pip install matplotlib --upgrade )

supxlabel y supylabel

    fig.supxlabel('common_x')
    fig.supylabel('common_y')

Voir l'exemple :

import matplotlib.pyplot as plt

for tl, cl in zip([True, False, False], [False, False, True]):
    fig = plt.figure(constrained_layout=cl, tight_layout=tl)

    gs = fig.add_gridspec(2, 3)

    ax = dict()

    ax['A'] = fig.add_subplot(gs[0, 0:2])
    ax['B'] = fig.add_subplot(gs[1, 0:2])
    ax['C'] = fig.add_subplot(gs[:, 2])

    ax['C'].set_xlabel('Booger')
    ax['B'].set_xlabel('Booger')
    ax['A'].set_ylabel('Booger Y')
    fig.suptitle(f'TEST: tight_layout={tl} constrained_layout={cl}')
    fig.supxlabel('XLAgg')
    fig.supylabel('YLAgg')

    plt.show()

enter image description here enter image description here enter image description here

voir plus

42voto

Piotr Migdal Points 525

Sans sharex=True, sharey=True vous obtenez :

enter image description here

Avec ça, tu devrais l'avoir plus belle :

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

Mais si vous voulez ajouter des étiquettes supplémentaires, vous ne devez les ajouter qu'aux graphiques de bord :

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

Ajouter une étiquette pour chaque parcelle gâcherait tout (il existe peut-être un moyen de détecter automatiquement les étiquettes répétées, mais je n'en connais pas).

14voto

Marius Points 188

Depuis la commande :

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

que vous avez utilisé renvoie un tuple constitué de la figure et d'une liste d'instances d'axes, il suffit déjà de faire quelque chose comme (attention, j'ai modifié fig,ax à 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')

Si vous voulez modifier certains détails d'une sous-intrigue spécifique, vous pouvez y accéder via axes[i] donde i itère sur vos sous-plans.

Il pourrait également être très utile d'inclure un

fig.tight_layout()

à la fin du fichier, avant le plt.show() afin d'éviter le chevauchement des étiquettes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X