Skip to content

Matplotlib Subplots : Créer des Figures Multipanneaux avec plt.subplots()

Updated on

Les figures à panneau unique suffisent rarement pour une analyse réelle. Vous devez comparer des distributions côte à côte, montrer un nuage de points à côté de ses résidus, ou présenter quatre métriques dans une mise en page de tableau de bord. Sans subplots, vous créeriez des figures séparées qui perdent leur relation visuelle lorsqu'elles sont présentées ensemble.

La fonction plt.subplots() de Matplotlib crée des figures multipanneaux avec des axes partagés, un dimensionnement cohérent et des mises en page flexibles. Ce guide couvre tout, des grilles basiques aux mises en page asymétriques avancées.

📚

Subplots Basiques

Ligne Unique

import matplotlib.pyplot as plt
import numpy as np
 
x = np.linspace(0, 10, 100)
 
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
 
axes[0].plot(x, np.sin(x))
axes[0].set_title('Sinus')
 
axes[1].plot(x, np.cos(x), color='orange')
axes[1].set_title('Cosinus')
 
axes[2].plot(x, np.tan(x), color='green')
axes[2].set_ylim(-5, 5)
axes[2].set_title('Tangente')
 
plt.tight_layout()
plt.show()

Disposition en Grille

import matplotlib.pyplot as plt
import numpy as np
 
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
 
x = np.linspace(0, 10, 100)
 
axes[0, 0].plot(x, x, 'b-')
axes[0, 0].set_title('Linéaire')
 
axes[0, 1].plot(x, x**2, 'r-')
axes[0, 1].set_title('Quadratique')
 
axes[1, 0].plot(x, np.sqrt(x), 'g-')
axes[1, 0].set_title('Racine Carrée')
 
axes[1, 1].plot(x, np.log(x + 1), 'm-')
axes[1, 1].set_title('Logarithmique')
 
plt.tight_layout()
plt.show()

Axes Partagés

Le partage des axes assure des échelles cohérentes pour la comparaison :

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(2, 1.5, 1000)
 
# Partager l'axe X
fig, axes = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
axes[0].hist(data1, bins=30, color='steelblue', alpha=0.7)
axes[0].set_ylabel('Nombre')
axes[0].set_title('Distribution A')
 
axes[1].hist(data2, bins=30, color='coral', alpha=0.7)
axes[1].set_ylabel('Nombre')
axes[1].set_xlabel('Valeur')
axes[1].set_title('Distribution B')
 
plt.tight_layout()
plt.show()
import matplotlib.pyplot as plt
import numpy as np
 
# Partager les axes X et Y
fig, axes = plt.subplots(2, 3, figsize=(12, 8), sharex=True, sharey=True)
 
for i, ax in enumerate(axes.flat):
    data = np.random.randn(100)
    ax.hist(data, bins=20, color=f'C{i}', alpha=0.7)
    ax.set_title(f'Échantillon {i+1}')
 
plt.tight_layout()
plt.show()

Contrôle de l'Espacement et de la Mise en Page

tight_layout()

Ajuste automatiquement l'espacement pour éviter les chevauchements :

import matplotlib.pyplot as plt
 
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
# ... ajouter des graphiques ...
plt.tight_layout()  # Auto-correction de l'espacement
plt.show()

subplots_adjust()

Contrôle manuel de l'espacement :

import matplotlib.pyplot as plt
 
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
plt.subplots_adjust(
    left=0.1,    # Marge gauche
    right=0.95,  # Marge droite
    top=0.92,    # Marge supérieure
    bottom=0.08, # Marge inférieure
    wspace=0.3,  # Espace horizontal entre subplots
    hspace=0.4,  # Espace vertical entre subplots
)
plt.show()

Ajouter un Super Titre

import matplotlib.pyplot as plt
import numpy as np
 
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
fig.suptitle('Fonctions Trigonométriques', fontsize=16, fontweight='bold')
 
x = np.linspace(0, 2 * np.pi, 100)
for ax, func, name in zip(axes, [np.sin, np.cos, np.tan], ['sin', 'cos', 'tan']):
    ax.plot(x, func(x))
    ax.set_title(name)
 
plt.tight_layout()
plt.show()

GridSpec pour des Mises en Page Asymétriques

Lorsque vous avez besoin de panneaux de tailles différentes, utilisez GridSpec :

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
 
fig = plt.figure(figsize=(12, 8))
gs = gridspec.GridSpec(2, 3, figure=fig)
 
# Grand panneau gauche (s'étend sur 2 lignes)
ax1 = fig.add_subplot(gs[:, 0])
ax1.plot(np.random.randn(100).cumsum())
ax1.set_title('Série Temporelle (2 lignes)')
 
# Panneaux supérieurs droits
ax2 = fig.add_subplot(gs[0, 1])
ax2.bar(['A', 'B', 'C'], [3, 7, 5])
ax2.set_title('Diagramme en Barres')
 
ax3 = fig.add_subplot(gs[0, 2])
ax3.scatter(np.random.randn(50), np.random.randn(50))
ax3.set_title('Nuage de Points')
 
# Panneau inférieur large (s'étend sur 2 colonnes)
ax4 = fig.add_subplot(gs[1, 1:])
ax4.hist(np.random.randn(500), bins=30, color='coral')
ax4.set_title('Histogramme (2 colonnes)')
 
plt.tight_layout()
plt.show()

subplot2grid pour une Mise en Page Positionnelle

import matplotlib.pyplot as plt
import numpy as np
 
fig = plt.figure(figsize=(12, 8))
 
# (lignes, cols), (ligne_début, col_début), rowspan, colspan
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
ax2 = plt.subplot2grid((3, 3), (0, 2), rowspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 0))
ax4 = plt.subplot2grid((3, 3), (1, 1))
ax5 = plt.subplot2grid((3, 3), (2, 0), colspan=3)
 
ax1.set_title('Haut Large')
ax2.set_title('Droite Haut')
ax3.set_title('Milieu Gauche')
ax4.set_title('Milieu Centre')
ax5.set_title('Bas Pleine Largeur')
 
plt.tight_layout()
plt.show()

Itérer sur les Subplots

import matplotlib.pyplot as plt
import numpy as np
 
# Aplatir le tableau axes pour une itération facile
fig, axes = plt.subplots(2, 3, figsize=(12, 8))
 
datasets = [np.random.randn(100) for _ in range(6)]
colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6', '#1abc9c']
 
for ax, data, color, i in zip(axes.flat, datasets, colors, range(6)):
    ax.hist(data, bins=20, color=color, alpha=0.7)
    ax.set_title(f'Jeu de Données {i+1}')
    ax.set_xlabel('Valeur')
    ax.set_ylabel('Nombre')
 
plt.tight_layout()
plt.show()

Supprimer les Subplots Vides

Lorsque vous avez moins de graphiques que de positions dans la grille :

import matplotlib.pyplot as plt
import numpy as np
 
fig, axes = plt.subplots(2, 3, figsize=(12, 8))
data_count = 5  # Seulement 5 jeux de données pour 6 emplacements
 
for i, ax in enumerate(axes.flat):
    if i < data_count:
        ax.plot(np.random.randn(50).cumsum())
        ax.set_title(f'Graphique {i+1}')
    else:
        ax.set_visible(False)  # Masquer le subplot vide
 
plt.tight_layout()
plt.show()

Exploration Interactive Multipanneau

Pour une exploration visuelle rapide où vous souhaitez comparer différentes vues du même jeu de données de manière interactive, PyGWalker (opens in a new tab) vous permet de créer des tableaux de bord en glissant-déposant des colonnes dans Jupyter -- sans code de subplot nécessaire :

import pandas as pd
import pygwalker as pyg
 
df = pd.read_csv('your_data.csv')
walker = pyg.walk(df)

FAQ

Comment créer des subplots dans Matplotlib ?

Utilisez fig, axes = plt.subplots(lignes, colonnes) pour créer une figure avec une grille de subplots. Accédez aux axes individuels avec axes[ligne, colonne] pour les grilles ou axes[i] pour les lignes/colonnes uniques. Appelez toujours plt.tight_layout() à la fin pour éviter les chevauchements d'étiquettes.

Comment partager des axes entre subplots ?

Passez sharex=True ou sharey=True à plt.subplots(). Par exemple, fig, axes = plt.subplots(2, 1, sharex=True) fait partager la même échelle de l'axe x aux deux subplots. C'est utile pour comparer des distributions ou des séries temporelles.

Comment créer des subplots de tailles différentes ?

Utilisez matplotlib.gridspec.GridSpec pour des mises en page asymétriques. Créez une grille et utilisez la notation de tranche pour couvrir plusieurs cellules : ax = fig.add_subplot(gs[0, :2]) crée un subplot couvrant les deux premières colonnes de la première ligne.

Comment ajuster l'espacement entre les subplots ?

Appelez plt.tight_layout() pour un espacement automatique. Pour un contrôle manuel, utilisez plt.subplots_adjust(wspace=0.3, hspace=0.4)wspace est l'espacement horizontal et hspace est l'espacement vertical.

Comment ajouter un titre au-dessus de tous les subplots ?

Utilisez fig.suptitle('Mon Titre', fontsize=16) pour ajouter un super-titre au-dessus de tous les subplots. Vous devrez peut-être ajuster la marge supérieure avec plt.subplots_adjust(top=0.92) ou appeler plt.tight_layout() pour éviter les chevauchements.

Conclusion

Le plt.subplots() de Matplotlib est la base des figures multipanneaux. Utilisez-le avec (lignes, colonnes) pour les grilles régulières, sharex/sharey pour des échelles cohérentes, tight_layout() pour l'espacement automatique, et GridSpec pour les mises en page asymétriques. Pour une itération rapide, aplatissez le tableau axes avec axes.flat et parcourez-le. Ces modèles couvrent la grande majorité des besoins de visualisation multipanneau.

📚