Matplotlib fill_between : remplissage conditionnel, bandes et corrections isin()
Publié le
Mis à jour le

fill_between colore la zone entre deux courbes y (ou entre une courbe et une baseline). C'est l'outil standard pour les bandes de confiance, les mises en évidence « au-dessus / en dessous » et les zones d'intérêt sur les graphiques en lignes.
Syntaxe rapide
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 200)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots()
ax.plot(x, y1, label="sin")
ax.plot(x, y2, label="cos")
ax.fill_between(x, y1, y2, color="0.7", alpha=0.4)
ax.legend()
plt.show()| Objectif | Motif |
|---|---|
| Remplir entre deux séries | ax.fill_between(x, y1, y2, alpha=0.3) |
| Remplir sous une ligne | ax.fill_between(x, 0, y, alpha=0.3) |
| Uniquement là où une condition tient | where=(y1 > y2) (même longueur que x) |
| Filtre d'index / de catégorie | where=df.index.isin([...]) — pas le in Python |
| Bords plus lisses sur les conditions | interpolate=True |
- Runcell Science : l'alternative open source à Claude Science pour la recherche
- Empêcher un Mac de se mettre en veille : capot fermé, Codex et Claude Code
- OpenClaw vs ZeroClaw vs Pi Agent vs Nanobot : quelle stack d’agents IA choisir en 2026 ?
- Comment Claude Code analyse un notebook Jupyter en Data Science : capacités réelles et limites
- Claude Code routines : triggers, cron jobs et automatisation d’agents IA
- Claude Code Desktop : activer le mode Bypass permissions
- Comment Créer Deux Agents Python avec le Protocole A2A de Google - Tutoriel Étape par Étape
- Top 10 bibliothèques de visualisation de données en Python en pleine croissance en 2025
Ce que fait fill_between
Matplotlib dessine un polygone de (x, y1) à (x, y2) et le remplit. x, y1 et y2 doivent avoir la même longueur (ou y1/y2 peuvent être des scalaires).
Cette seule idée couvre la plupart des tâches « mettre en évidence cette région » sans inventer des patches sur mesure.
Remplissage de base entre deux courbes
Cet exemple remplit tout l'espace entre sinus et cosinus :
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 300)
y1 = np.sin(x)
y2 = np.cos(x)
fig, ax = plt.subplots(figsize=(7.2, 4.2))
ax.plot(x, y1, label="sin(x)", color="#2563eb", lw=2)
ax.plot(x, y2, label="cos(x)", color="#dc2626", lw=2)
ax.fill_between(x, y1, y2, color="#94a3b8", alpha=0.45)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend(loc="upper right")
plt.show()
Réglages utiles :
alpha— garder les remplissages translucides pour que les lignes restent lisiblescolor/facecolor— couleur de remplissagelinewidth=0— masquer le bord du polygone s'il entre en conflit avec les styles de lignelabel=— inclure le remplissage dans la légende quand il représente une vraie catégorie
Remplissages conditionnels avec where=
Passez un tableau booléen (même longueur que x) pour peindre seulement une partie de la bande. Utilisez deux appels si vous voulez deux couleurs :
fig, ax = plt.subplots(figsize=(7.2, 4.2))
ax.plot(x, y1, label="sin(x)", color="#2563eb", lw=2)
ax.plot(x, y2, label="cos(x)", color="#dc2626", lw=2)
ax.fill_between(
x, y1, y2,
where=(y1 > y2),
interpolate=True,
color="#22c55e",
alpha=0.35,
label="sin > cos",
)
ax.fill_between(
x, y1, y2,
where=(y1 <= y2),
interpolate=True,
color="#f97316",
alpha=0.30,
label="sin ≤ cos",
)
ax.legend(loc="upper right", ncol=2)
plt.show()
Pourquoi interpolate=True compte
Sans interpolation, le remplissage peut se couper avec des bords verticaux en blocs là où la condition bascule entre points d'échantillonnage. interpolate=True estime le croisement pour que la mise en évidence suive les courbes plus proprement. Préférez-le pour les séries continues denses ; il est moins important pour des axes x catégoriels clairsemés.
Motif bande de confiance / d'erreur
Un usage réel très courant est « moyenne ± incertitude » :
t = np.linspace(0, 12, 200)
mean = np.sin(t / 1.5) + 0.15 * t
std = 0.35 + 0.08 * np.abs(np.cos(t))
fig, ax = plt.subplots(figsize=(7.2, 4.2))
ax.plot(t, mean, color="#0f766e", lw=2.2, label="estimate")
ax.fill_between(t, mean - std, mean + std, color="#14b8a6", alpha=0.28, label="±1σ band")
ax.set_xlabel("time")
ax.set_ylabel("value")
ax.legend(loc="upper left")
plt.show()
La même idée fonctionne pour des quantiles (p10/p90), des plages de prévision ou des enveloppes min/max. Tracez la ligne centrale après ou avec un z-order plus élevé si le remplissage paraît trop présent.
Dépannage : remplir seulement pour certaines catégories / mois
Le trafic de recherche arrive souvent sur cette page après un essai raté du type :
# Broken ideas
where = plotMonths.index in ["January", "February", "March"] # ValueError / nonsense
where = [m in ["January", "February", "March"] for m in plotMonths.index] # may work, but isin is cleanerCe qui ne va pas
array in listn'est pas élément par élément. Les objets NumPy/pandas lèventValueErrorou renvoient un booléen unique ambigu.- Il vous faut un vecteur booléen aligné sur
x, pas un seul True/False pour tout le tableau.
Correction : isin() (ou np.isin)
Exemple complet et exécutable avec des libellés de mois catégoriels :
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"]
df = pd.DataFrame(
{
"A": [12, 14, 13, 15, 18, 17, 16, 19],
"B": [10, 11, 12, 14, 13, 15, 14, 16],
},
index=months,
)
fig, ax = plt.subplots(figsize=(7.2, 4.2))
ax.plot(df.index, df["A"], marker="o", label="series A")
ax.plot(df.index, df["B"], marker="o", label="series B")
ax.fill_between(
np.arange(len(df)),
df["A"],
df["B"],
where=df.index.isin(["Jan", "Feb", "Mar"]),
color="#38bdf8",
alpha=0.35,
label="Q1 highlight",
)
ax.set_xticks(range(len(df)), df.index)
ax.legend(loc="upper left")
plt.show()
Notes :
- Pour un DatetimeIndex, préférez des masques booléens comme
(df.index.month <= 3)ou.isinsur des libellés normalisés. - Quand x est des libellés catégoriels sur l'axe, passer des positions entières à
fill_between(comme ci-dessus) est souvent plus fiable que des catégories en chaînes. - Gardez la longueur de
whereégale au tableau x que vous passez.
Pièges courants
| Piège | Symptôme | Correction |
|---|---|---|
| Longueurs différentes | ValueError: ... not the same size | Aligner x, y1, y2, where |
Utiliser le in Python sur Index/tableau | ValueError ou remplissage vide | index.isin([...]) / np.isin |
Oublier alpha | Le remplissage masque les lignes | alpha=0.2–0.4 |
| Légende hors graphique coupée en PNG | Légende tronquée | Voir légende hors du graphique + bbox_inches="tight" |
| Bords de condition laids | Régions en blocs | interpolate=True |
Pour les graphiques multi-séries, associez les remplissages à des styles de ligne clairs issus des tracés multi-lignes. Si la figure paraît étroite après annotations et bandes, ajustez la taille de figure avant de batailler sur le placement de la légende.
fill_between vs fill_betweenx
fill_between(x, y1, y2)— remplissage vertical entre deux valeurs y le long de x (le plus courant).fill_betweenx(y, x1, x2)— remplissage horizontal entre deux valeurs x le long de y (utile pour profils verticaux, bandes de densité, plages type tornado).
La même idée de where= s'applique aux deux.
FAQ
Conclusion
ax.fill_between(x, y1, y2) est une petite API au fort impact visuel : comparer des séries, montrer l'incertitude et éclairer des régions. Utilisez where= quand le récit est conditionnel, isin/masques booléens plutôt que le in Python pour les libellés, et gardez alpha bas pour que les données restent prioritaires.
Guides connexes
- Légende Matplotlib hors du graphique — garder les libellés de séries lisibles à côté des zones remplies
- Tracés multi-lignes Matplotlib — graphiques multi-séries qui se marient bien avec les remplissages
- Taille de figure Matplotlib — de la place pour bandes, libellés et légendes
- Matplotlib savefig coupe les libellés — exporter sans rognage
- Subplots Matplotlib — mises en page en panneaux pour plusieurs séries remplies
- Annotations et texte Matplotlib — étiqueter les régions que vous venez de remplir