Skip to content
Tópicos
Matplotlib
Matplotlib fill_between: Preencher Entre Curvas, where= e Bandas

Matplotlib fill_between: Preencher Entre Curvas, where= e Bandas

Publicado em

Atualizado em

Use plt.fill_between / ax.fill_between para preencher entre curvas, destacar condições com where=, montar banda de confiança e corrigir ValueError ao filtrar índices com isin().

fill_between preenche a área entre duas curvas em y (ou entre uma curva e uma linha de base). É a ferramenta padrão para banda de confiança, destaques “acima/abaixo” e regiões em gráficos de linha.

Sintaxe rápida

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()
ObjetivoPadrão
Preencher entre duas sériesax.fill_between(x, y1, y2, alpha=0.3)
Preencher sob uma linhaax.fill_between(x, 0, y, alpha=0.3)
Só onde uma condição valewhere=(y1 > y2) (mesmo comprimento que x)
Filtro de índice / categoriawhere=df.index.isin([...]) — não o in do Python
Bordas mais suaves em condiçõesinterpolate=True

O que o fill_between faz

O Matplotlib desenha um polígono de (x, y1) até (x, y2) e o preenche. x, y1 e y2 precisam ter o mesmo comprimento (ou y1/y2 podem ser escalares).

Essa ideia única cobre a maior parte das tarefas de “destacar esta região” sem inventar patches manuais.

Preenchimento básico entre duas curvas

Este exemplo preenche tudo entre seno e cosseno:

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

Controles úteis:

  • alpha — deixe o preenchimento translúcido para as linhas permanecerem legíveis
  • color / facecolor — cor do preenchimento
  • linewidth=0 — esconda a borda do polígono se ela brigar com o estilo das linhas
  • label= — inclua o preenchimento na legenda quando ele representar uma categoria real

Preenchimentos condicionais com where=

Passe um array booleano (mesmo comprimento que x) para pintar só parte da faixa. Use duas chamadas se quiser duas cores:

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

Por que interpolate=True importa

Sem interpolação, o preenchimento pode cortar com bordas verticais “em degrau” onde a condição muda entre pontos amostrados. interpolate=True estima o cruzamento para o destaque acompanhar as curvas com mais limpeza. Prefira em séries contínuas densas; em eixos x categóricos e esparsos importa menos.

Padrão de banda de confiança / erro

Um uso muito comum no mundo real é “média ± incerteza”:

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

A mesma ideia vale para quantis (p10/p90), faixas de previsão ou envelopes min/máx. Plote a linha central depois ou com z-order maior se o preenchimento ficar barulhento demais.

Troubleshooting: preencher só para algumas categorias / meses

Muita busca chega nesta página depois de uma tentativa que falha, assim:

# 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

O que dá errado

  • array in list não é elemento a elemento. Objetos NumPy/pandas levantam ValueError ou devolvem um único booleano ambíguo.
  • Você precisa de um vetor booleano alinhado com x, não de um True/False para o array inteiro.

Correção: isin() (ou np.isin)

Exemplo completo e executável com rótulos de mês categóricos:

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

Notas:

  • Para DatetimeIndex, prefira máscaras booleanas como (df.index.month <= 3) ou .isin em rótulos normalizados.
  • Quando x no eixo são rótulos categóricos, passar posições inteiras para fill_between (como acima) costuma ser mais confiável do que categorias em string.
  • Mantenha o comprimento de where igual ao do array x que você passa.

Armadilhas comuns

ArmadilhaSintomaCorreção
Comprimentos diferentesValueError: ... not the same sizeAlinhe x, y1, y2, where
Usar in do Python em Index/arrayValueError ou preenchimento vazioindex.isin([...]) / np.isin
Esquecer alphaPreenchimento esconde as linhasalpha=0.2–0.4
Legenda fora cortada no PNGLegenda cortadaVeja legenda fora do gráfico + bbox_inches="tight"
Bordas feias na condiçãoRegiões em blocointerpolate=True

Em gráficos multi-série, combine preenchimentos com estilos de linha claros de múltiplos gráficos de linha. Se a figura ficar apertada depois de anotações e bandas, ajuste o tamanho da figura antes de brigar com a legenda.

fill_between vs fill_betweenx

  • fill_between(x, y1, y2) — preenchimento vertical entre dois valores y ao longo de x (o mais comum).
  • fill_betweenx(y, x1, x2) — preenchimento horizontal entre dois valores x ao longo de y (útil para perfis verticais, faixas de densidade, intervalos estilo tornado).

A mesma ideia de where= vale para os dois.

FAQ

Conclusão

ax.fill_between(x, y1, y2) é a API pequena com retorno visual grande: comparar séries, mostrar incerteza e destacar regiões. Use where= quando a história for condicional, prefira isin/máscaras booleanas em vez do in do Python para rótulos, e mantenha alpha baixo para os dados continuarem no comando.

Guias relacionados