Seaborn Boxplot: Como criar e personalizar gráficos de caixa em Python
Updated on
Entender como seus dados estão distribuídos é uma das tarefas mais fundamentais na análise de dados. Você precisa identificar valores discrepantes, comparar grupos e identificar assimetria antes de executar qualquer modelo ou tirar conclusões. No entanto, olhar números brutos em um DataFrame raramente lhe dá o quadro completo. Um seaborn boxplot resolve esse problema ao condensar uma distribuição inteira em um gráfico compacto e legível que mostra a mediana, a dispersão e os valores discrepantes de relance.
Neste guia, você aprenderá como criar, personalizar e interpretar gráficos de caixa usando a biblioteca seaborn do Python. Cada exemplo de código usa conjuntos de dados reais integrados no seaborn para que você possa executá-los imediatamente em um notebook Jupyter.
O que é um gráfico de caixa?
Um gráfico de caixa (também chamado de diagrama de caixa e bigodes) é uma maneira padronizada de exibir uma distribuição com base em cinco estatísticas resumidas:
| Componente | O que representa |
|---|---|
| Linha de mediana | O valor médio do conjunto de dados (percentil 50) |
| Caixa (IQR) | O intervalo interquartil, abrangendo de Q1 (percentil 25) a Q3 (percentil 75) |
| Bigode inferior | O menor ponto de dados dentro de Q1 - 1,5 * IQR |
| Bigode superior | O maior ponto de dados dentro de Q3 + 1,5 * IQR |
| Pontos discrepantes | Pontos de dados individuais que ficam fora do intervalo dos bigodes |
A caixa captura os 50% centrais de seus dados. Uma caixa alta significa alta variabilidade; uma caixa curta significa que seus valores se agrupam de forma compacta. Quando a linha de mediana fica fora do centro dentro da caixa, a distribuição é assimétrica. Pontos além dos bigodes sinalizam possíveis valores discrepantes que merecem investigação.
Os gráficos de caixa são particularmente eficazes quando você precisa comparar distribuições em várias categorias lado a lado, tornando-os um elemento básico da análise exploratória de dados.
Sintaxe básica do Seaborn Boxplot
Criar um boxplot no seaborn requer apenas uma função: sns.boxplot(). No mínimo, você passa os dados e especifica qual variável plotar.
import seaborn as sns
import matplotlib.pyplot as plt
# Carregar um conjunto de dados integrado
tips = sns.load_dataset("tips")
# Boxplot vertical básico
sns.boxplot(data=tips, y="total_bill")
plt.title("Distribuição da conta total")
plt.show()Isso produz uma única caixa mostrando a distribuição dos valores de total_bill. A função calcula automaticamente os quartis, bigodes e valores discrepantes para você.
Para dividir os dados por uma variável categórica, adicione o parâmetro x:
sns.boxplot(data=tips, x="day", y="total_bill")
plt.title("Conta total por dia da semana")
plt.show()Agora você vê quatro caixas lado a lado, uma para cada dia, facilitando a comparação dos padrões de gastos ao longo da semana.
Criação de boxplots a partir de diferentes formatos de dados
O Seaborn lida com múltiplos formatos de dados elegantemente. Aqui estão os cenários mais comuns.
DataFrame em formato longo (dados organizados)
A maioria das funções do seaborn funciona melhor com dados em formato longo (organizados) onde cada linha é uma observação única e as colunas representam variáveis. O conjunto de dados tips já está neste formato:
# Formato longo: cada linha é uma visita ao restaurante
sns.boxplot(data=tips, x="day", y="total_bill")
plt.show()DataFrame em formato amplo
Se seus dados têm uma coluna por grupo (formato amplo), o seaborn ainda pode produzir boxplots diretamente:
import pandas as pd
import numpy as np
# Criar dados em formato amplo
np.random.seed(42)
wide_df = pd.DataFrame({
"Group A": np.random.normal(50, 10, 100),
"Group B": np.random.normal(60, 15, 100),
"Group C": np.random.normal(45, 8, 100),
})
sns.boxplot(data=wide_df)
plt.title("Comparação de três grupos (dados em formato amplo)")
plt.ylabel("Valor")
plt.show()O Seaborn trata automaticamente cada coluna como uma categoria separada e as plota lado a lado.
Selecionando colunas específicas do DataFrame
Quando você deseja visualizar apenas certas colunas numéricas de um DataFrame maior, filtre-as primeiro:
iris = sns.load_dataset("iris")
# Selecionar apenas colunas de medição
measurement_cols = iris[["sepal_length", "sepal_width", "petal_length", "petal_width"]]
sns.boxplot(data=measurement_cols)
plt.title("Distribuições de características de Iris")
plt.xticks(rotation=15)
plt.show()Personalizando seu Seaborn Boxplot
O Seaborn fornece opções extensas para adaptar a aparência e o comportamento de seus gráficos de caixa.
Cores e paletas
Altere o esquema de cores usando o parâmetro palette ou defina uma única cor para todas as caixas:
# Usar uma paleta nomeada
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set2")
plt.title("Paleta personalizada")
plt.show()# Cor única para todas as caixas
sns.boxplot(data=tips, x="day", y="total_bill", color="skyblue")
plt.title("Cor uniforme")
plt.show()Opções de paleta populares incluem "Set2", "pastel", "muted", "deep", "husl" e "coolwarm".
Orientação horizontal vs vertical
Troque os eixos para criar um boxplot horizontal. Isso é útil quando os rótulos de categoria são longos:
sns.boxplot(data=tips, x="total_bill", y="day", orient="h")
plt.title("Boxplot horizontal")
plt.show()Boxplots agrupados com o parâmetro hue
O parâmetro hue divide cada categoria em subgrupos, adicionando uma segunda dimensão à sua comparação:
sns.boxplot(data=tips, x="day", y="total_bill", hue="sex")
plt.title("Conta total por dia e gênero")
plt.legend(title="Gênero")
plt.show()Cada dia agora mostra duas caixas (uma por gênero), facilitando a comparação dos padrões de gastos masculinos e femininos em cada dia da semana.
Controlando o tamanho da figura
Os gráficos do Seaborn herdam o tamanho da figura do matplotlib. Defina-o antes de chamar sns.boxplot():
plt.figure(figsize=(12, 6))
sns.boxplot(data=tips, x="day", y="total_bill", hue="smoker", palette="muted")
plt.title("Conta total por dia e status de fumante")
plt.show()Adicionando sobreposições de gráfico de enxame ou faixa
Um boxplot resume a distribuição, mas oculta os pontos de dados individuais. Sobreponha um gráfico de enxame ou faixa para mostrar cada observação:
plt.figure(figsize=(10, 6))
sns.boxplot(data=tips, x="day", y="total_bill", palette="pastel")
sns.stripplot(data=tips, x="day", y="total_bill", color="0.3", size=3, jitter=True, alpha=0.5)
plt.title("Boxplot com sobreposição de gráfico de faixa")
plt.show()plt.figure(figsize=(10, 6))
sns.boxplot(data=tips, x="day", y="total_bill", palette="pastel")
sns.swarmplot(data=tips, x="day", y="total_bill", color="0.25", size=3, alpha=0.6)
plt.title("Boxplot com sobreposição de gráfico de enxame")
plt.show()O gráfico de enxame organiza os pontos para que não se sobreponham, dando uma melhor noção da densidade dos dados. Use gráficos de faixa quando você tiver muitos pontos de dados e gráficos de enxame quando tiver menos (gráficos de enxame podem ficar lentos com milhares de pontos).
Referência de parâmetros do Seaborn Boxplot
Aqui está uma referência rápida para os parâmetros mais comumente usados em sns.boxplot():
| Parâmetro | Tipo | Descrição |
|---|---|---|
data | DataFrame, array ou lista | Estrutura de dados de entrada |
x, y | str ou array | Variáveis para os eixos |
hue | str | Variável de agrupamento para subgrupos codificados por cores |
order | lista de str | Ordem para plotar os níveis categóricos |
hue_order | lista de str | Ordem para os níveis de hue |
orient | "v" ou "h" | Orientação do gráfico |
color | str | Cor única para todos os elementos |
palette | str, lista ou dict | Cores para diferentes níveis |
saturation | float | Proporção de saturação original (0 a 1) |
fill | bool | Se deve preencher a caixa com cor (seaborn >= 0.13) |
width | float | Largura das caixas (padrão 0,8) |
dodge | bool | Se deve deslocar grupos de hue ao longo do eixo categórico |
fliersize | float | Tamanho dos marcadores de valores discrepantes |
linewidth | float | Largura das linhas que emolduram a caixa |
whis | float ou tupla | Comprimento dos bigodes como múltiplo do IQR (padrão 1,5) |
ax | matplotlib Axes | Objeto Axes no qual desenhar o gráfico |
Comparando distribuições
Várias colunas lado a lado
Ao comparar distribuições de várias características numéricas, transforme seu DataFrame em formato longo:
iris = sns.load_dataset("iris")
# Transformar de formato amplo para longo
iris_long = iris.melt(id_vars="species", var_name="measurement", value_name="cm")
plt.figure(figsize=(12, 6))
sns.boxplot(data=iris_long, x="measurement", y="cm", palette="Set3")
plt.title("Comparação de medições de Iris")
plt.show()Comparações agrupadas com hue
Combine uma categoria e uma variável de agrupamento para comparar distribuições em duas dimensões:
plt.figure(figsize=(14, 6))
sns.boxplot(data=iris_long, x="measurement", y="cm", hue="species", palette="husl")
plt.title("Medições de Iris por espécie")
plt.legend(title="Espécie", bbox_to_anchor=(1.05, 1), loc="upper left")
plt.tight_layout()
plt.show()Isso produz um boxplot agrupado onde cada tipo de medição mostra três caixas (uma por espécie), tornando a comparação entre espécies imediata.
Seaborn Boxplot vs Matplotlib Boxplot
Tanto o seaborn quanto o matplotlib podem produzir gráficos de caixa, mas diferem significativamente em facilidade de uso e qualidade visual.
| Característica | Seaborn sns.boxplot() | Matplotlib ax.boxplot() |
|---|---|---|
| Estética padrão | Polida, pronta para publicação | Básica, estilo mínimo |
| Integração DataFrame | Suporte nativo para pandas DataFrames | Requer extração manual de arrays |
| Agrupamento de hue | Parâmetro hue integrado | Posicionamento e coloração manual |
| Paletas | Atribuição de paleta em uma linha | Gerenciamento manual de lista de cores |
| Anotações estatísticas | Sobreposição fácil com gráficos de enxame/faixa | Requer sobreposições de dispersão manual |
| Profundidade de personalização | Moderada (delega ao matplotlib) | Controle completo de baixo nível |
| Curva de aprendizado | Baixa | Média a alta |
| Verbosidade do código | 1-2 linhas para um gráfico agrupado | 10-20 linhas para equivalente |
Veredicto: Use seaborn para análise exploratória rápida e visuais limpos. Recorra ao matplotlib quando precisar de controle em nível de pixel sobre cada elemento.
# Boxplot Matplotlib (mais verboso)
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 5))
data_by_day = [tips[tips["day"] == d]["total_bill"].values for d in ["Thur", "Fri", "Sat", "Sun"]]
bp = ax.boxplot(data_by_day, labels=["Thur", "Fri", "Sat", "Sun"], patch_artist=True)
for patch, color in zip(bp["boxes"], ["#8dd3c7", "#ffffb3", "#bebada", "#fb8072"]):
patch.set_facecolor(color)
ax.set_title("Boxplot Matplotlib (estilo manual)")
ax.set_ylabel("Conta total")
plt.show()# Equivalente Seaborn (conciso)
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set3",
order=["Thur", "Fri", "Sat", "Sun"])
plt.title("Boxplot Seaborn (uma linha)")
plt.show()Gráfico de caixa vs Gráfico de violino: quando usar qual
O Seaborn também oferece sns.violinplot(), que mostra a forma completa de densidade da distribuição em vez de apenas as estatísticas resumidas. Aqui está quando escolher cada um:
| Critério | Gráfico de caixa | Gráfico de violino |
|---|---|---|
| Melhor para | Estatísticas resumidas rápidas e detecção de valores discrepantes | Entender a forma completa da distribuição |
| Mostra valores discrepantes | Sim, como pontos individuais | Não (absorvidos na curva de densidade) |
| Mostra bimodalidade | Não | Sim (visível como duas protuberâncias) |
| Legibilidade | Alta, mesmo para públicos não técnicos | Requer mais explicação |
| Eficiência de espaço | Compacto | Mais largo, ocupa mais espaço horizontal |
| Desempenho | Renderização rápida | Mais lento com grandes conjuntos de dados (cálculo KDE) |
Regra geral: Comece com um boxplot para verificações rápidas. Mude para um gráfico de violino se suspeitar que a distribuição tem múltiplos picos ou uma forma incomum.
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set2", ax=axes[0])
axes[0].set_title("Gráfico de caixa")
sns.violinplot(data=tips, x="day", y="total_bill", palette="Set2", ax=axes[1])
axes[1].set_title("Gráfico de violino")
plt.tight_layout()
plt.show()Alternativa interativa: explore distribuições com PyGWalker
Os gráficos de caixa estáticos funcionam bem para relatórios e notebooks, mas quando você está na fase de exploração inicial, geralmente quer arrastar diferentes variáveis para dentro e fora de um gráfico sem reescrever código toda vez.
PyGWalker (opens in a new tab) é uma biblioteca Python de código aberto que transforma qualquer pandas DataFrame em uma interface de exploração visual interativa semelhante ao Tableau diretamente dentro do Jupyter Notebook. Você pode criar gráficos de caixa, gráficos de violino, histogramas, gráficos de dispersão e muito mais simplesmente arrastando campos para os eixos. Nenhuma alteração de código é necessária.
pip install pygwalkerimport pandas as pd
import pygwalker as pyg
tips = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv")
walker = pyg.walk(tips)Depois que a interface do usuário carregar, arraste day para o eixo X e total_bill para o eixo Y, depois selecione o tipo de marca de boxplot. Você pode mudar instantaneamente para um gráfico de violino, adicionar dimensões de cor ou filtrar por qualquer coluna, tudo sem escrever uma única linha de código extra.
Isso é particularmente valioso para equipes onde nem todos escrevem Python. Compartilhe o notebook e deixe as partes interessadas explorarem os dados por si mesmas.
| Executar PyGWalker no Kaggle (opens in a new tab) | Executar PyGWalker no Google Colab (opens in a new tab) | PyGWalker no GitHub (opens in a new tab) |
|---|
Perguntas frequentes
Como removo valores discrepantes de um seaborn boxplot?
Defina o parâmetro whis para um valor maior (por exemplo, whis=3.0) para estender os bigodes e reduzir o número de pontos mostrados como valores discrepantes. Alternativamente, defina flierprops={"marker": ""} para ocultar completamente os marcadores de valores discrepantes enquanto mantém o cálculo dos bigodes inalterado.
Posso plotar um seaborn boxplot sem usar um DataFrame?
Sim. Você pode passar arrays ou listas brutas diretamente: sns.boxplot(x=["A"]*50 + ["B"]*50, y=np.random.randn(100)). No entanto, usar um DataFrame com colunas nomeadas é recomendado porque gera automaticamente rótulos de eixo.
Como altero o estilo do marcador de valores discrepantes em sns.boxplot?
Passe um dicionário para o parâmetro flierprops: sns.boxplot(data=tips, x="day", y="total_bill", flierprops={"marker": "D", "markerfacecolor": "red", "markersize": 5}). Isso muda os marcadores de valores discrepantes para diamantes vermelhos.
Qual é a diferença entre hue e x no seaborn boxplot?
O parâmetro x define o agrupamento categórico primário no eixo horizontal. O parâmetro hue adiciona um agrupamento secundário dentro de cada categoria, exibido como caixas coloridas lado a lado. Use x sozinho para comparações simples e adicione hue quando quiser dividir cada categoria por uma segunda variável como gênero ou status.
Como salvo um seaborn boxplot em um arquivo?
Depois de criar o gráfico, chame plt.savefig("boxplot.png", dpi=300, bbox_inches="tight"). Os gráficos do Seaborn são figuras do matplotlib por baixo, portanto todos os métodos de salvamento do matplotlib funcionam. Os formatos suportados incluem PNG, PDF, SVG e EPS.
Conclusão
O seaborn boxplot é uma das maneiras mais rápidas de entender como seus dados estão distribuídos, detectar valores discrepantes e comparar grupos. Com sns.boxplot(), você passa de um DataFrame bruto para uma visualização de qualidade de publicação em uma única linha de código. O parâmetro hue adiciona comparações agrupadas sem esforço extra, e sobrepor gráficos de faixa ou enxame preenche os detalhes de pontos de dados individuais que os gráficos de caixa abstraem.
Para análise estática em notebooks e relatórios, os boxplots do seaborn são difíceis de superar. Quando você precisa de uma camada de exploração interativa sobre seus dados do pandas, ferramentas como PyGWalker (opens in a new tab) permitem construir e iterar visualizações sem alterações de código.
Comece com os exemplos básicos acima, experimente com paletas e sobreposições, e você terá um kit de ferramentas visual confiável para qualquer pergunta de distribuição de dados que aparecer.