Matplotlib fill_between: Bereich füllen, where und Konfidenzband
Veröffentlicht am
Aktualisiert am

fill_between füllt die Fläche zwischen zwei y-Kurven (oder zwischen einer Kurve und einer Baseline). Es ist das Standardwerkzeug für Konfidenzbänder, „oberhalb/unterhalb“-Highlights und Region-Markierungen auf Liniendiagrammen.
Schnelle Syntax
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()| Ziel | Muster |
|---|---|
| Zwischen zwei Serien füllen | ax.fill_between(x, y1, y2, alpha=0.3) |
| Unter einer Linie füllen | ax.fill_between(x, 0, y, alpha=0.3) |
| Nur wo eine Bedingung gilt | where=(y1 > y2) (gleiche Länge wie x) |
| Index-/Kategorie-Filter | where=df.index.isin([...]) — nicht Python-in |
| Glattere Kanten bei Bedingungen | interpolate=True |
- Runcell Science: Open-Source-Alternative zu Claude Science für Forschungsteams
- Mac Ruhezustand verhindern: Codex, Claude Code und KI-Agenten weiterlaufen lassen
- OpenClaw vs ZeroClaw vs Pi Agent vs Nanobot: Welchen KI-Agenten-Stack sollten Sie 2026 wählen?
- Wie Claude Code Jupyter Notebooks analysiert: Data Science, Grenzen und die bessere Alternative
- Claude Code Routines: KI-Cronjobs für Agenten
- Claude Code Desktop: Bypass permissions aktivieren
- Schritt-für-Schritt-Anleitung zur Erstellung von zwei Python-Agenten mit Googles A2A-Protokoll
- Die Top 10 wachsenden Data Visualization Libraries in Python im Jahr 2025
Was fill_between macht
Matplotlib baut ein Polygon von (x, y1) nach (x, y2) und füllt es. x, y1 und y2 müssen dieselbe Länge haben (oder y1/y2 dürfen Skalare sein).
Mit dieser einen Idee erledigt man die meisten „diese Region hervorheben“-Aufgaben, ohne eigene Patches zu bauen.
Basis: Fläche zwischen zwei Kurven
Dieses Beispiel füllt alles zwischen Sinus und Kosinus:
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()
Nützliche Schalter:
alpha— Füllung transparent halten, damit Linien lesbar bleibencolor/facecolor— Füllfarbelinewidth=0— Polygonkante ausblenden, wenn sie mit Linienstilen kollidiertlabel=— die Füllung in die Legende aufnehmen, wenn sie eine echte Kategorie darstellt
Bedingte Füllungen mit where=
Ein boolesches Array (gleiche Länge wie x) sorgt dafür, dass nur Teile des Bands gefärbt werden. Zwei Aufrufe, wenn zwei Farben gewünscht sind:
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()
Warum interpolate=True zählt
Ohne Interpolation kann die Füllung an Stellen, an denen die Bedingung zwischen Sample-Punkten wechselt, mit blockigen vertikalen Kanten abbrechen. interpolate=True schätzt den Schnittpunkt, sodass das Highlight den Kurven sauberer folgt. Bei dichten, kontinuierlichen Serien bevorzugen; bei spärlichen, kategorialen x-Achsen ist es weniger wichtig.
Muster: Konfidenz- / Fehlerband
Ein sehr häufiges Praxis-Muster ist „Mittelwert ± Unsicherheit“:
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()
Dieselbe Idee gilt für Quantile (p10/p90), Forecast-Bereiche oder Min/Max-Hüllen. Die Mittellinie nach der Füllung plotten oder mit höherem z-order, wenn die Füllung zu dominant wirkt.
Troubleshooting: nur bestimmte Kategorien / Monate füllen
Suchtraffic landet oft hier nach fehlgeschlagenen Versuchen wie:
# 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 cleanerWas schiefgeht
array in listist nicht elementweise. NumPy-/pandas-Objekte werfenValueErroroder liefern einen einzelnen, mehrdeutigen Boolean.- Gebraucht wird ein boolescher Vektor, ausgerichtet an
x, nicht ein True/False für das ganze Array.
Fix: isin() (oder np.isin)
Vollständiges, lauffähiges Beispiel mit kategorialen Monats-Labels:
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()
Hinweise:
- Bei DatetimeIndex boolesche Masken wie
(df.index.month <= 3)oder.isinauf normalisierten Labels bevorzugen. - Liegen auf der Achse kategoriale Labels, sind Integer-Positionen an
fill_between(wie oben) oft zuverlässiger als String-Kategorien. wheremuss dieselbe Länge haben wie das übergebene x-Array.
Typische Fallen
| Falle | Symptom | Fix |
|---|---|---|
| Längen-Mismatch | ValueError: ... not the same size | x, y1, y2, where angleichen |
Python-in auf Index/Array | ValueError oder leere Füllung | index.isin([...]) / np.isin |
alpha vergessen | Füllung verdeckt Linien | alpha=0.2–0.4 |
| Außenlegende im PNG abgeschnitten | Legende fehlt | Siehe Legende außerhalb des Plots + bbox_inches="tight" |
| Hässliche Bedingungskanten | blockige Regionen | interpolate=True |
Bei Multi-Serien-Charts Füllungen mit klaren Linienstilen aus mehreren Linienplots kombinieren. Wirkt die Figur nach Annotationen und Bändern eng, zuerst die Figure-Größe anpassen, bevor man an der Legende feilt.
fill_between vs fill_betweenx
fill_between(x, y1, y2)— vertikale Füllung zwischen zwei y-Werten über x (häufigster Fall).fill_betweenx(y, x1, x2)— horizontale Füllung zwischen zwei x-Werten über y (nützlich für vertikale Profile, Dichte-Streifen, tornado-artige Bereiche).
Die where=-Idee gilt für beide.
FAQ
Fazit
ax.fill_between(x, y1, y2) ist die kleine API mit großem visuellen Effekt: Serien vergleichen, Unsicherheit zeigen, Regionen markieren. Bei bedingten Geschichten zu where= greifen, Labels mit isin/booleschen Masken statt Python-in filtern und alpha niedrig halten, damit die Daten im Vordergrund bleiben.
Verwandte Anleitungen
- Matplotlib Legende außerhalb des Plots — Serienlabels neben gefüllten Regionen lesbar halten
- Matplotlib mehrere Linienplots — Multi-Serien-Charts, die gut mit Füllungen passen
- Matplotlib Figure-Größe — Platz für Bänder, Labels und Legenden
- Matplotlib savefig schneidet Labels ab — Export ohne Clipping
- Matplotlib Subplots — Panel-Layouts für mehrere gefüllte Serien
- Matplotlib Annotationen und Text — Regionen beschriften, die gerade gefüllt wurden