Seaborn Boxplot: Cómo crear y personalizar gráficos de caja en Python
Updated on
Comprender cómo se distribuyen sus datos es una de las tareas más fundamentales en el análisis de datos. Necesita detectar valores atípicos, comparar grupos e identificar la asimetría antes de ejecutar cualquier modelo o sacar conclusiones. Sin embargo, mirar números sin procesar en un DataFrame rara vez le brinda la imagen completa. Un seaborn boxplot resuelve este problema al condensar una distribución completa en un gráfico compacto y legible que muestra la mediana, la dispersión y los valores atípicos de un vistazo.
En esta guía, aprenderá cómo crear, personalizar e interpretar gráficos de caja usando la biblioteca seaborn de Python. Cada ejemplo de código utiliza conjuntos de datos reales incorporados en seaborn para que pueda ejecutarlos inmediatamente en un cuaderno Jupyter.
¿Qué es un gráfico de caja?
Un gráfico de caja (también llamado diagrama de caja y bigotes) es una forma estandarizada de mostrar una distribución basada en cinco estadísticas de resumen:
| Componente | Lo que representa |
|---|---|
| Línea de mediana | El valor medio del conjunto de datos (percentil 50) |
| Caja (IQR) | El rango intercuartílico, que abarca desde Q1 (percentil 25) hasta Q3 (percentil 75) |
| Bigote inferior | El punto de datos más pequeño dentro de Q1 - 1.5 * IQR |
| Bigote superior | El punto de datos más grande dentro de Q3 + 1.5 * IQR |
| Puntos atípicos | Puntos de datos individuales que caen fuera del rango de bigotes |
La caja captura el 50% medio de sus datos. Una caja alta significa alta variabilidad; una caja corta significa que sus valores se agrupan estrechamente. Cuando la línea de mediana está descentrada dentro de la caja, la distribución está sesgada. Los puntos más allá de los bigotes marcan posibles valores atípicos que merecen investigación.
Los gráficos de caja son particularmente efectivos cuando necesita comparar distribuciones en varias categorías lado a lado, lo que los convierte en un elemento básico del análisis exploratorio de datos.
Sintaxis básica de Seaborn Boxplot
Crear un boxplot en seaborn requiere solo una función: sns.boxplot(). Como mínimo, pasa los datos y especifica qué variable trazar.
import seaborn as sns
import matplotlib.pyplot as plt
# Cargar un conjunto de datos incorporado
tips = sns.load_dataset("tips")
# Boxplot vertical básico
sns.boxplot(data=tips, y="total_bill")
plt.title("Distribución de la cuenta total")
plt.show()Esto produce una sola caja que muestra la distribución de los valores de total_bill. La función calcula automáticamente los cuartiles, bigotes y valores atípicos para usted.
Para dividir los datos por una variable categórica, agregue el parámetro x:
sns.boxplot(data=tips, x="day", y="total_bill")
plt.title("Cuenta total por día de la semana")
plt.show()Ahora ve cuatro cajas una al lado de la otra, una por cada día, lo que facilita la comparación de los patrones de gasto durante la semana.
Creación de boxplots a partir de diferentes formatos de datos
Seaborn maneja múltiples formatos de datos con elegancia. Aquí están los escenarios más comunes.
DataFrame de formato largo (datos ordenados)
La mayoría de las funciones de seaborn funcionan mejor con datos de formato largo (ordenados) donde cada fila es una sola observación y las columnas representan variables. El conjunto de datos tips ya está en este formato:
# Formato largo: cada fila es una visita al restaurante
sns.boxplot(data=tips, x="day", y="total_bill")
plt.show()DataFrame de formato ancho
Si sus datos tienen una columna por grupo (formato ancho), seaborn aún puede producir boxplots directamente:
import pandas as pd
import numpy as np
# Crear datos de formato ancho
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("Comparación de tres grupos (datos de formato ancho)")
plt.ylabel("Valor")
plt.show()Seaborn trata automáticamente cada columna como una categoría separada y las traza una al lado de la otra.
Selección de columnas específicas de DataFrame
Cuando solo desea visualizar ciertas columnas numéricas de un DataFrame más grande, primero fíltrelas:
iris = sns.load_dataset("iris")
# Seleccionar solo columnas de medición
measurement_cols = iris[["sepal_length", "sepal_width", "petal_length", "petal_width"]]
sns.boxplot(data=measurement_cols)
plt.title("Distribuciones de características de Iris")
plt.xticks(rotation=15)
plt.show()Personalización de su Seaborn Boxplot
Seaborn proporciona opciones extensas para adaptar la apariencia y el comportamiento de sus gráficos de caja.
Colores y paletas
Cambie el esquema de colores usando el parámetro palette o establezca un solo color para todas las cajas:
# Usar una paleta con nombre
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set2")
plt.title("Paleta personalizada")
plt.show()# Color único para todas las cajas
sns.boxplot(data=tips, x="day", y="total_bill", color="skyblue")
plt.title("Color uniforme")
plt.show()Las opciones de paleta populares incluyen "Set2", "pastel", "muted", "deep", "husl" y "coolwarm".
Orientación horizontal vs vertical
Intercambie los ejes para crear un boxplot horizontal. Esto es útil cuando las etiquetas de categoría son largas:
sns.boxplot(data=tips, x="total_bill", y="day", orient="h")
plt.title("Boxplot horizontal")
plt.show()Boxplots agrupados con el parámetro hue
El parámetro hue divide cada categoría en subgrupos, agregando una segunda dimensión a su comparación:
sns.boxplot(data=tips, x="day", y="total_bill", hue="sex")
plt.title("Cuenta total por día y género")
plt.legend(title="Género")
plt.show()Cada día ahora muestra dos cajas (una por género), lo que facilita la comparación de los patrones de gasto masculinos y femeninos en cada día de la semana.
Controlar el tamaño de la figura
Los gráficos de Seaborn heredan el tamaño de figura de matplotlib. Configúrelo antes de llamar a sns.boxplot():
plt.figure(figsize=(12, 6))
sns.boxplot(data=tips, x="day", y="total_bill", hue="smoker", palette="muted")
plt.title("Cuenta total por día y estado de fumador")
plt.show()Agregar superposiciones de gráficos de enjambre o tira
Un boxplot resume la distribución, pero oculta los puntos de datos individuales. Superponga un gráfico de enjambre o tira para mostrar cada observación:
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 con superposición de gráfico de tira")
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 con superposición de gráfico de enjambre")
plt.show()El gráfico de enjambre organiza los puntos para que no se superpongan, dando una mejor sensación de la densidad de datos. Use gráficos de tira cuando tenga muchos puntos de datos y gráficos de enjambre cuando tenga menos (los gráficos de enjambre pueden volverse lentos con miles de puntos).
Referencia de parámetros de Seaborn Boxplot
Aquí hay una referencia rápida para los parámetros más comúnmente usados en sns.boxplot():
| Parámetro | Tipo | Descripción |
|---|---|---|
data | DataFrame, array o lista | Estructura de datos de entrada |
x, y | str o array | Variables para los ejes |
hue | str | Variable de agrupación para subgrupos codificados por colores |
order | lista de str | Orden para trazar los niveles categóricos |
hue_order | lista de str | Orden para los niveles de hue |
orient | "v" o "h" | Orientación del gráfico |
color | str | Color único para todos los elementos |
palette | str, lista o dict | Colores para diferentes niveles |
saturation | float | Proporción de saturación original (0 a 1) |
fill | bool | Si se llena la caja con color (seaborn >= 0.13) |
width | float | Ancho de las cajas (predeterminado 0.8) |
dodge | bool | Si se desplazan los grupos de hue a lo largo del eje categórico |
fliersize | float | Tamaño de los marcadores de valores atípicos |
linewidth | float | Ancho de las líneas que enmarcan la caja |
whis | float o tupla | Longitud de bigotes como múltiplo de IQR (predeterminado 1.5) |
ax | matplotlib Axes | Objeto Axes en el que dibujar el gráfico |
Comparación de distribuciones
Varias columnas una al lado de la otra
Al comparar distribuciones de varias características numéricas, convierta su DataFrame a formato largo:
iris = sns.load_dataset("iris")
# Convertir de formato ancho a largo
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("Comparación de mediciones de Iris")
plt.show()Comparaciones agrupadas con hue
Combine tanto una categoría como una variable de agrupación para comparar distribuciones en dos dimensiones:
plt.figure(figsize=(14, 6))
sns.boxplot(data=iris_long, x="measurement", y="cm", hue="species", palette="husl")
plt.title("Mediciones de Iris por especie")
plt.legend(title="Especie", bbox_to_anchor=(1.05, 1), loc="upper left")
plt.tight_layout()
plt.show()Esto produce un boxplot agrupado donde cada tipo de medición muestra tres cajas (una por especie), haciendo inmediata la comparación entre especies.
Seaborn Boxplot vs Matplotlib Boxplot
Tanto seaborn como matplotlib pueden producir gráficos de caja, pero difieren significativamente en facilidad de uso y calidad visual.
| Característica | Seaborn sns.boxplot() | Matplotlib ax.boxplot() |
|---|---|---|
| Estética predeterminada | Pulida, lista para publicación | Básica, estilo mínimo |
| Integración de DataFrame | Soporte nativo para pandas DataFrames | Requiere extraer arrays manualmente |
| Agrupación de hue | Parámetro hue incorporado | Posicionamiento y coloración manual |
| Paletas | Asignación de paleta de una línea | Gestión manual de lista de colores |
| Anotaciones estadísticas | Superposición fácil con gráficos de enjambre/tira | Requiere superposiciones de dispersión manual |
| Profundidad de personalización | Moderada (delega a matplotlib) | Control completo de bajo nivel |
| Curva de aprendizaje | Baja | Media a alta |
| Verbosidad del código | 1-2 líneas para un gráfico agrupado | 10-20 líneas para equivalente |
Veredicto: Use seaborn para análisis exploratorio rápido y visualizaciones limpias. Recurra a matplotlib cuando necesite control a nivel de píxel sobre cada elemento.
# Boxplot de Matplotlib (más 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 de Matplotlib (estilo manual)")
ax.set_ylabel("Cuenta total")
plt.show()# Equivalente de Seaborn (conciso)
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set3",
order=["Thur", "Fri", "Sat", "Sun"])
plt.title("Boxplot de Seaborn (una línea)")
plt.show()Gráfico de caja vs gráfico de violín: cuándo usar cuál
Seaborn también ofrece sns.violinplot(), que muestra la forma completa de densidad de la distribución en lugar de solo las estadísticas de resumen. Aquí es cuando elegir cada uno:
| Criterio | Gráfico de caja | Gráfico de violín |
|---|---|---|
| Mejor para | Estadísticas de resumen rápidas y detección de valores atípicos | Comprender la forma completa de la distribución |
| Muestra valores atípicos | Sí, como puntos individuales | No (absorbidos en la curva de densidad) |
| Muestra bimodalidad | No | Sí (visible como dos protuberancias) |
| Legibilidad | Alta, incluso para audiencias no técnicas | Requiere más explicación |
| Eficiencia de espacio | Compacto | Más ancho, ocupa más espacio horizontal |
| Rendimiento | Renderizado rápido | Más lento con conjuntos de datos grandes (cálculo de KDE) |
Regla de oro: Comience con un boxplot para controles rápidos. Cambie a un gráfico de violín si sospecha que la distribución tiene múltiples picos o una forma inusual.
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 caja")
sns.violinplot(data=tips, x="day", y="total_bill", palette="Set2", ax=axes[1])
axes[1].set_title("Gráfico de violín")
plt.tight_layout()
plt.show()Alternativa interactiva: explore distribuciones con PyGWalker
Los gráficos de caja estáticos funcionan bien para informes y cuadernos, pero cuando está en la fase de exploración temprana, a menudo desea arrastrar diferentes variables dentro y fuera de un gráfico sin reescribir código cada vez.
PyGWalker (opens in a new tab) es una biblioteca de Python de código abierto que convierte cualquier pandas DataFrame en una interfaz de exploración visual interactiva similar a Tableau directamente dentro de Jupyter Notebook. Puede crear gráficos de caja, gráficos de violín, histogramas, gráficos de dispersión y más simplemente arrastrando campos a los ejes. No se necesitan cambios de código.
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)Una vez que se carga la interfaz de usuario, arrastre day al eje X y total_bill al eje Y, luego seleccione el tipo de marca de gráfico de caja. Puede cambiar instantáneamente a un gráfico de violín, agregar dimensiones de color o filtrar por cualquier columna, todo sin escribir una sola línea de código adicional.
Esto es particularmente valioso para equipos donde no todos escriben Python. Comparta el cuaderno y permita que las partes interesadas exploren los datos por sí mismas.
| Ejecutar PyGWalker en Kaggle (opens in a new tab) | Ejecutar PyGWalker en Google Colab (opens in a new tab) | PyGWalker en GitHub (opens in a new tab) |
|---|
Preguntas frecuentes
¿Cómo elimino valores atípicos de un seaborn boxplot?
Establezca el parámetro whis en un valor más grande (por ejemplo, whis=3.0) para extender los bigotes y reducir el número de puntos mostrados como valores atípicos. Alternativamente, establezca flierprops={"marker": ""} para ocultar completamente los marcadores de valores atípicos mientras mantiene sin cambios el cálculo de bigotes.
¿Puedo trazar un seaborn boxplot sin usar un DataFrame?
Sí. Puede pasar arrays o listas sin procesar directamente: sns.boxplot(x=["A"]*50 + ["B"]*50, y=np.random.randn(100)). Sin embargo, se recomienda usar un DataFrame con columnas nombradas porque genera automáticamente etiquetas de eje.
¿Cómo cambio el estilo de marcador de valores atípicos en sns.boxplot?
Pase un diccionario al parámetro flierprops: sns.boxplot(data=tips, x="day", y="total_bill", flierprops={"marker": "D", "markerfacecolor": "red", "markersize": 5}). Esto cambia los marcadores de valores atípicos a diamantes rojos.
¿Cuál es la diferencia entre hue y x en seaborn boxplot?
El parámetro x define la agrupación categórica primaria en el eje horizontal. El parámetro hue agrega una agrupación secundaria dentro de cada categoría, mostrada como cajas de colores una al lado de la otra. Use x solo para comparaciones simples y agregue hue cuando desee desglosar cada categoría por una segunda variable como género o estado.
¿Cómo guardo un seaborn boxplot en un archivo?
Después de crear el gráfico, llame a plt.savefig("boxplot.png", dpi=300, bbox_inches="tight"). Los gráficos de Seaborn son figuras de matplotlib por debajo, por lo que todos los métodos de guardado de matplotlib funcionan. Los formatos compatibles incluyen PNG, PDF, SVG y EPS.
Conclusión
El seaborn boxplot es una de las formas más rápidas de comprender cómo se distribuyen sus datos, detectar valores atípicos y comparar grupos. Con sns.boxplot(), pasa de un DataFrame sin procesar a una visualización de calidad de publicación en una sola línea de código. El parámetro hue agrega comparaciones agrupadas sin esfuerzo adicional, y superponer gráficos de tira o enjambre completa los detalles de puntos de datos individuales que los gráficos de caja abstraen.
Para análisis estáticos en cuadernos e informes, los boxplots de seaborn son difíciles de superar. Cuando necesite una capa de exploración interactiva sobre sus datos de pandas, herramientas como PyGWalker (opens in a new tab) le permiten construir e iterar visualizaciones sin cambios de código.
Comience con los ejemplos básicos anteriores, experimente con paletas y superposiciones, y tendrá un conjunto de herramientas visuales confiable para cualquier pregunta de distribución de datos que se le presente.