Matplotlib fill_between: Preencher Entre Curvas, where= e Bandas
Publicado em
Atualizado em

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()| Objetivo | Padrão |
|---|---|
| Preencher entre duas séries | ax.fill_between(x, y1, y2, alpha=0.3) |
| Preencher sob uma linha | ax.fill_between(x, 0, y, alpha=0.3) |
| Só onde uma condição vale | where=(y1 > y2) (mesmo comprimento que x) |
| Filtro de índice / categoria | where=df.index.isin([...]) — não o in do Python |
| Bordas mais suaves em condições | interpolate=True |
- Runcell Science: alternativa open source ao Claude Science para pesquisa com IA
- Como impedir o Mac de dormir: mantenha Codex, Claude Code e agentes de IA rodando
- OpenClaw vs ZeroClaw vs Pi Agent vs Nanobot: qual stack de agentes de IA você deve escolher em 2026?
- Como o Claude Code analisa notebooks Jupyter em Data Science: capacidade real, limites e alternativa melhor
- Claude Code Routines: rotinas e cron jobs para agentes de IA
- Claude Code Desktop: como ativar Bypass permissions
- Como Construir Dois Agentes Python com o Protocolo A2A do Google - Tutorial Passo a Passo
- Top 10 bibliotecas de visualização de dados em Python em 2025
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()
Controles úteis:
alpha— deixe o preenchimento translúcido para as linhas permanecerem legíveiscolor/facecolor— cor do preenchimentolinewidth=0— esconda a borda do polígono se ela brigar com o estilo das linhaslabel=— 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()
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()
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 cleanerO que dá errado
array in listnão é elemento a elemento. Objetos NumPy/pandas levantamValueErrorou 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()
Notas:
- Para DatetimeIndex, prefira máscaras booleanas como
(df.index.month <= 3)ou.isinem 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
whereigual ao do array x que você passa.
Armadilhas comuns
| Armadilha | Sintoma | Correção |
|---|---|---|
| Comprimentos diferentes | ValueError: ... not the same size | Alinhe x, y1, y2, where |
Usar in do Python em Index/array | ValueError ou preenchimento vazio | index.isin([...]) / np.isin |
Esquecer alpha | Preenchimento esconde as linhas | alpha=0.2–0.4 |
| Legenda fora cortada no PNG | Legenda cortada | Veja legenda fora do gráfico + bbox_inches="tight" |
| Bordas feias na condição | Regiões em bloco | interpolate=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
- Legenda Matplotlib fora do gráfico — manter rótulos de série legíveis ao lado de regiões preenchidas
- Múltiplos gráficos de linha no Matplotlib — gráficos multi-série que combinam bem com preenchimentos
- Tamanho de figura no Matplotlib — espaço para bandas, rótulos e legendas
- savefig corta rótulos no Matplotlib — exportar sem cortar
- Subplots no Matplotlib — layouts em painéis para várias séries preenchidas
- Anotações e texto no Matplotlib — rotular as regiões que você acabou de preencher