Seaborn es una biblioteca de visualización estadística para Python construida sobre Matplotlib y estrechamente integrada con las estructuras de datos de Pandas. Proporciona una interfaz de alto nivel para producir gráficos estadísticos atractivos y expresivos con poco código, y desde la serie 0.12 ofrece además la interfaz declarativa seaborn.objects, basada en objetos Plot, Mark, Stat, Move y Scale, que se consolida como API de futuro en la versión 0.13.
Arquitectura: Seaborn sobre Matplotlib y Pandas
Seaborn no sustituye a Matplotlib, lo complementa. Internamente cada gráfico de Seaborn se dibuja sobre un Axes de Matplotlib, lo que permite combinar ambas bibliotecas con naturalidad. Los datos se consumen en formato DataFrame de Pandas (o Series, diccionario, array NumPy), y Seaborn se encarga de los cálculos estadísticos (estimadores, intervalos de confianza, densidades) y de la estética por defecto.
flowchart TB
pandas[(DataFrame Pandas 2.x · backend PyArrow)] --> seaborn[Seaborn 0.13+]
seaborn --> fl[Funciones figure-level · relplot / displot / catplot]
seaborn --> al[Funciones axes-level · scatterplot / histplot / boxplot]
seaborn --> obj[seaborn.objects · Plot · Mark · Stat]
fl --> facetgrid[FacetGrid]
al --> axes[matplotlib.axes.Axes]
obj --> axes
facetgrid --> figure[matplotlib.figure.Figure]
axes --> figure
figure --> render[PNG · PDF · SVG · HTML]
Familias de gráficos y funciones unificadas
La API tradicional se organiza alrededor de tres funciones figure-level unificadas que reemplazan la elección manual entre variantes: relplot (relacionales), displot (distribuciones) y catplot (categóricos). Cada una admite un parámetro kind que selecciona la representación concreta, y delega en una función axes-level equivalente cuando se necesita más control.
flowchart LR
sns[seaborn] --> rel[Relacionales · relplot]
sns --> dist[Distribución · displot]
sns --> cat[Categóricos · catplot]
sns --> reg[Regresión · lmplot]
sns --> mat[Matriciales · heatmap · clustermap]
sns --> multi[Multi-plot · FacetGrid · PairGrid · JointGrid]
rel --> scatter[scatterplot]
rel --> line[lineplot]
dist --> hist[histplot]
dist --> kde[kdeplot]
dist --> ecdf[ecdfplot]
cat --> box[boxplot]
cat --> violin[violinplot]
cat --> bar[barplot]
cat --> strip[stripplot]
cat --> swarm[swarmplot]
reg --> regplot[regplot]
reg --> resid[residplot]
Interfaz tradicional vs seaborn.objects
seaborn.objects es una reescritura declarativa inspirada en la Grammar of Graphics. En lugar de llamar a funciones con muchos parámetros, se componen objetos Mark (qué se dibuja), Stat (qué transformación estadística se aplica) y Move (cómo se disponen los elementos). La API tradicional sigue plenamente soportada y es la vía principal para la mayoría de casos; la interfaz de objetos aporta mayor flexibilidad cuando se necesitan capas y transformaciones compuestas.
flowchart LR
subgraph trad[API tradicional]
t1[sns.scatterplot · imperativa] --> t2[hue, size, style como argumentos]
t2 --> t3[facetado mediante relplot / catplot / displot]
end
subgraph obj[seaborn.objects · declarativa]
o1[so.Plot] --> o2[.add: Mark + Stat + Move]
o2 --> o3[.facet · .scale · .theme]
o3 --> o4[.layout · .on · .save]
end
trad --> pick{caso de uso}
obj --> pick
pick -->|exploración rápida| trad
pick -->|composición multi-capa| obj
Ejemplo tradicional
import seaborn as sns
sns.set_theme(style="whitegrid", context="notebook")
df = sns.load_dataset("penguins").dropna()
sns.relplot(
data=df,
x="bill_length_mm",
y="bill_depth_mm",
hue="species",
style="sex",
col="island",
kind="scatter"
)
Equivalente con seaborn.objects
import seaborn as sns
import seaborn.objects as so
df = sns.load_dataset("penguins").dropna()
(
so.Plot(df, x="bill_length_mm", y="bill_depth_mm", color="species", marker="sex")
.add(so.Dot())
.facet(col="island")
.scale(color="deep")
.theme({"axes.grid": True})
)
Grids: FacetGrid, PairGrid y JointGrid
Para composiciones multi-plot, Seaborn ofrece tres clases de grid complementarias. FacetGrid crea cuadrículas condicionadas por variables categóricas (col, row, col_wrap); PairGrid genera matrices de pares sobre varias variables numéricas; JointGrid combina un gráfico central con distribuciones marginales. Las funciones figure-level relplot, displot, catplot, lmplot, pairplot y jointplot devuelven internamente estas clases.
flowchart TB
grid[Grids de Seaborn] --> facet[FacetGrid · condicionado por col/row]
grid --> pair[PairGrid · matriz numérica N×N]
grid --> joint[JointGrid · central + marginales]
facet --> relplot[relplot · catplot · displot · lmplot]
pair --> pairplot[pairplot]
joint --> jointplot[jointplot]
facet --> map[.map · .map_dataframe · función personalizada]
pair --> diag[.map_diag · .map_offdiag · .map_upper · .map_lower]
joint --> plot[.plot_joint · .plot_marginals]
Flujo típico de análisis exploratorio con Seaborn
Un EDA bien estructurado con Seaborn alterna bloques univariantes, bivariantes y multivariantes, apoyándose en las funciones figure-level para recorrer rápidamente grupos y en la objects API o en Matplotlib cuando se necesita componer capas o exportar informes de producción.
flowchart TB
start[DataFrame Pandas 2.x · PyArrow] --> clean[Limpieza · astype category · dropna]
clean --> theme[sns.set_theme · paleta + contexto + estilo]
theme --> uni[Univariante · displot hist/kde/ecdf]
uni --> bi[Bivariante · jointplot · scatterplot · regplot]
bi --> multi[Multivariante · pairplot · heatmap · clustermap]
multi --> facet[Faceting · relplot / catplot · FacetGrid]
facet --> obj[Refinado · seaborn.objects]
obj --> export[Exportación · savefig PNG 200 dpi · PDF · SVG]
export --> informe[Informe · Jupyter · Streamlit · PDF]
Integración con Pandas 2.x y PyArrow
Seaborn 0.13 trabaja de forma directa con DataFrames que usan el backend PyArrow de Pandas 2.x (dtype_backend="pyarrow"), aprovechando dtypes nativos como string[pyarrow], int64[pyarrow] y tipos de fecha de mayor rendimiento. Las funciones aceptan tanto datos long-form (una observación por fila, columnas como variables) como wide-form (una variable por columna). La mayoría de gráficos estadísticos requieren long-form, que se obtiene con DataFrame.melt() cuando se parte de un esquema ancho.
import pandas as pd
import seaborn as sns
# Carga con backend PyArrow (Pandas 2.x)
df = pd.read_csv("ventas.csv", dtype_backend="pyarrow")
df["categoria"] = df["categoria"].astype("category")
sns.set_theme(style="whitegrid", context="notebook", palette="deep")
sns.catplot(data=df, x="mes", y="importe", hue="categoria", kind="bar", col="region", col_wrap=3)
Estilos, temas y paletas
sns.set_theme() configura de una sola llamada estilo (whitegrid, darkgrid, ticks, white, dark), contexto (paper, notebook, talk, poster) y paleta. Las paletas se clasifican en secuenciales (rocket, mako, crest), divergentes (vlag, icefire, coolwarm) y cualitativas (deep, muted, pastel, tab10). Para heatmaps de correlación centrados en cero, la convención es una paleta divergente; para categóricas con un orden natural, una secuencial; para grupos sin orden, una cualitativa accesible.
import seaborn as sns
sns.set_theme(style="whitegrid", context="notebook", palette="deep")
paleta_personalizada = sns.color_palette("husl", n_colors=5)
sns.set_palette(paleta_personalizada)
Ejemplos prácticos
Gráfico de dispersión con ajuste de regresión
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset("tips")
sns.lmplot(x="total_bill", y="tip", data=df, hue="smoker", height=5, aspect=1.3)
plt.show()
Distribuciones comparadas con displot y ecdf
import seaborn as sns
df = sns.load_dataset("penguins").dropna()
sns.displot(data=df, x="body_mass_g", hue="species", kind="ecdf")
sns.displot(data=df, x="body_mass_g", hue="species", kind="hist", kde=True, col="sex")
Matriz de correlación con heatmap
import seaborn as sns
df = sns.load_dataset("diamonds").select_dtypes("number")
sns.heatmap(df.corr(), annot=True, fmt=".2f", cmap="vlag", center=0, square=True)
Diferencias con otras bibliotecas
Seaborn vs Matplotlib
- Abstracción estadística: Seaborn resuelve en una llamada lo que en Matplotlib requiere cálculos manuales de bins, densidades o intervalos de confianza.
- Estética integrada: estilos y paletas accesibles vienen configurados sin ajustes adicionales.
- Axes Matplotlib por debajo: los gráficos axes-level de Seaborn aceptan
ax=y se integran en layouts creados conplt.subplotsoGridSpec.
Seaborn vs Plotly
- Interactividad: Plotly prioriza gráficos interactivos para dashboards y aplicaciones web; Seaborn se orienta a visualizaciones estáticas para análisis e informes.
- Curva de aprendizaje: Seaborn encaja mejor en flujos cortos de Jupyter; Plotly requiere más configuración para resultados estadísticos equivalentes.
Seaborn vs Altair
- Gramática declarativa: Altair está basado en Vega-Lite con JSON declarativo;
seaborn.objectsofrece una alternativa nativa en Python conPlot,MarkyStatsin serialización intermedia. - Ecosistema: Seaborn se apoya en Matplotlib; Altair se renderiza en el navegador.
Novedades recientes
seaborn.objects como interfaz de futuro
La API declarativa seaborn.objects, introducida en 0.12 y consolidada en 0.13, permite componer gráficos capa a capa con Plot, Mark, Stat, Move y Scale. La documentación oficial recomienda adoptarla progresivamente, sobre todo cuando se necesitan transformaciones compuestas o exportación a varias salidas.
Ejemplo: composición declarativa con objects
import seaborn.objects as so
import seaborn as sns
df = sns.load_dataset("diamonds").sample(1000, random_state=42)
(
so.Plot(df, x="carat", y="price", color="cut")
.add(so.Dot(alpha=0.5))
.add(so.Line(), so.PolyFit(order=2))
.scale(color="viridis")
.facet(col="clarity", wrap=4)
)
Funciones figure-level unificadas
relplot, displot y catplot son los puntos de entrada recomendados para gráficos relacionales, de distribución y categóricos. Aceptan kind="..." para elegir la representación, gestionan faceting, leyendas y tamaño de figura de forma coherente y delegan en las funciones axes-level equivalentes.
Backend PyArrow de Pandas 2.x
La integración con Pandas 2.x se ha pulido para DataFrames que usan dtype_backend="pyarrow", con dtypes de string y numéricos basados en Apache Arrow que reducen memoria y aceleran operaciones sobre conjuntos grandes.
Paletas accesibles y estilos mejorados
Seaborn amplía la selección de paletas perceptualmente uniformes (rocket, mako, crest, flare) y divergentes (vlag, icefire), junto a utilidades como sns.color_palette, sns.husl_palette y sns.diverging_palette para construir paletas accesibles adaptadas a daltonismo.
Buenas prácticas y recomendaciones
- Fijar el tema al inicio con
sns.set_theme()antes de dibujar nada para garantizar coherencia en todo el notebook o informe. - Elegir la paleta según el tipo de variable: secuencial para ordenada, divergente centrada en cero para correlaciones, cualitativa accesible para grupos.
- Preferir funciones figure-level (
relplot,displot,catplot) para exploración rápida con faceting; cambiar a axes-level cuando se compone conplt.subplots. - Reservar
seaborn.objectspara gráficos con varias capas, transformaciones compuestas o cuando se necesita un estilo declarativo explícito. - Exportar en alta resolución con
plt.savefig("figura.png", dpi=200, bbox_inches="tight")y también en PDF o SVG para informes. - Trabajar en long-form siempre que sea posible; usar
DataFrame.melt()para pasar de wide a long cuando los datos vengan en esquema ancho.
pip install --upgrade seaborn pandas pyarrow matplotlib
Comunidad y recursos adicionales
La comunidad de Seaborn es activa y ofrece tutoriales, foros y ejemplos de código. La documentación oficial (seaborn.pydata.org) mantiene guías extensas sobre la API tradicional y sobre seaborn.objects, con una galería de ejemplos reproducibles. Participar en Stack Overflow, el repositorio de GitHub o los canales de discusión del ecosistema PyData resulta útil para resolver dudas y compartir técnicas.