Skip to content
Thèmes
Matplotlib
Matplotlib fill_between: Conditional Fills, Bands, and isin() Fixes

Matplotlib fill_between : remplissage conditionnel, bandes et corrections isin()

Publié le

Mis à jour le

Utilisez plt.fill_between / ax.fill_between pour remplir entre courbes, where= pour les conditions, des bandes de confiance, et corriger ValueError avec isin() sur les index.

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()
ObjectifMotif
Remplir entre deux sériesax.fill_between(x, y1, y2, alpha=0.3)
Remplir sous une ligneax.fill_between(x, 0, y, alpha=0.3)
Uniquement là où une condition tientwhere=(y1 > y2) (même longueur que x)
Filtre d'index / de catégoriewhere=df.index.isin([...]) — pas le in Python
Bords plus lisses sur les conditionsinterpolate=True

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

Basic fill_between between sine and cosine

Réglages utiles :

  • alpha — garder les remplissages translucides pour que les lignes restent lisibles
  • color / facecolor — couleur de remplissage
  • linewidth=0 — masquer le bord du polygone s'il entre en conflit avec les styles de ligne
  • label= — 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()

Conditional fill_between using where

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

Confidence-style band with fill_between

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 cleaner

Ce qui ne va pas

  • array in list n'est pas élément par élément. Les objets NumPy/pandas lèvent ValueError ou 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()

Selected months highlighted with isin

Notes :

  • Pour un DatetimeIndex, préférez des masques booléens comme (df.index.month <= 3) ou .isin sur 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ègeSymptômeCorrection
Longueurs différentesValueError: ... not the same sizeAligner x, y1, y2, where
Utiliser le in Python sur Index/tableauValueError ou remplissage videindex.isin([...]) / np.isin
Oublier alphaLe remplissage masque les lignesalpha=0.2–0.4
Légende hors graphique coupée en PNGLégende tronquéeVoir légende hors du graphique + bbox_inches="tight"
Bords de condition laidsRégions en blocsinterpolate=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