Estructuras de datos en Seaborn

Básico
Seaborn
Seaborn
Actualizado: 18/04/2026

Long-form vs Wide-form: el formato que espera Seaborn

Una de las claves para usar Seaborn con eficacia es entender qué formato de datos esperan sus funciones. Seaborn trabaja preferentemente con datos en formato long-form (también llamado tidy data o datos ordenados), aunque muchas funciones también aceptan datos en formato wide-form.

Long-form (una observación por fila, una variable por columna):

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Ejemplo de datos long-form
datos_long = pd.DataFrame({
    "persona": ["Ana", "Ana", "Ana", "Luis", "Luis", "Luis"],
    "mes": ["Enero", "Febrero", "Marzo", "Enero", "Febrero", "Marzo"],
    "ventas": [150, 180, 200, 120, 160, 190]
})

print(datos_long)

Salida:

  persona      mes  ventas
0     Ana    Enero     150
1     Ana  Febrero     180
2     Ana    Marzo     200
3    Luis    Enero     120
4    Luis  Febrero     160
5    Luis    Marzo     190

Wide-form (cada variable en una columna separada):

# Ejemplo de datos wide-form
datos_wide = pd.DataFrame({
    "mes": ["Enero", "Febrero", "Marzo"],
    "Ana": [150, 180, 200],
    "Luis": [120, 160, 190]
})

print(datos_wide)

Salida:

       mes  Ana  Luis
0    Enero  150   120
1  Febrero  180   160
2    Marzo  200   190

Seaborn puede visualizar ambos formatos, pero la codificación visual (hue, size, style) es mucho más natural con long-form:

# Con long-form: el parámetro hue asigna color por persona automáticamente
sns.lineplot(data=datos_long, x="mes", y="ventas", hue="persona", marker="o")
plt.title("Ventas mensuales por persona (long-form)")
plt.show()

# Con wide-form: Seaborn usa las columnas como series
sns.lineplot(data=datos_wide.set_index("mes"), marker="o")
plt.title("Ventas mensuales (wide-form)")
plt.show()

Transformar datos de wide-form a long-form

La función pd.melt() convierte datos wide-form a long-form, que es el formato preferido por la mayoría de las funciones de Seaborn:

# Transformar wide-form a long-form
datos_long2 = pd.melt(
    datos_wide,
    id_vars=["mes"],           # columnas que se mantienen fijas
    var_name="persona",        # nombre de la nueva columna de variables
    value_name="ventas"        # nombre de la nueva columna de valores
)

print(datos_long2)
       mes  persona  ventas
0    Enero      Ana     150
1  Febrero      Ana     180
2    Marzo      Ana     200
3    Enero     Luis     120
4  Febrero     Luis     160
5    Marzo     Luis     190

Un ejemplo más complejo con el dataset de flights:

flights = sns.load_dataset("flights")
print("Long-form original:")
print(flights.head())

# Pivotar a wide-form
flights_wide = flights.pivot(index="month", columns="year", values="passengers")
print("\nWide-form:")
print(flights_wide.head())

# Seaborn puede visualizar directamente el formato wide-form en heatmap
plt.figure(figsize=(12, 6))
sns.heatmap(flights_wide, annot=True, fmt="d", cmap="YlOrRd", linewidths=0.5)
plt.title("Pasajeros por mes y año")
plt.show()

Cómo Seaborn infiere variables del DataFrame

Cuando pasas un DataFrame y nombres de columnas a las funciones de Seaborn, la biblioteca accede automáticamente a las columnas por nombre. Esto elimina la necesidad de extraer arrays manualmente:

penguins = sns.load_dataset("penguins")

# Seaborn accede a las columnas por nombre directamente
# No necesitas: x=penguins["bill_length_mm"], y=penguins["bill_depth_mm"]
sns.scatterplot(
    data=penguins,
    x="bill_length_mm",        # nombre de columna como string
    y="bill_depth_mm",
    hue="species",
    size="body_mass_g",
    style="sex",
    sizes=(30, 200),
    alpha=0.7
)
plt.title("Dimensiones del pico de pingüinos")
plt.show()

Seaborn también infiere automáticamente las etiquetas de los ejes a partir de los nombres de las columnas, lo que reduce el código de etiquetado manual.

Datos con tipos categóricos de Pandas

Cuando una columna tiene tipo category en Pandas, Seaborn la trata de forma especial: respeta el orden definido en las categorías y muestra solo las categorías presentes en los datos:

tips = sns.load_dataset("tips")

# Definir el orden de los días como categoría
dias_ordenados = ["Thur", "Fri", "Sat", "Sun"]
tips["day"] = pd.Categorical(tips["day"], categories=dias_ordenados, ordered=True)

# Seaborn respetará el orden de las categorías
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set2")
plt.title("Total de cuenta por día (con orden categórico)")
plt.show()

También es útil para controlar el orden en gráficos de barras y categóricos:

# Usar el parámetro order para controlar el orden sin necesidad de categorías
sns.countplot(
    data=tips,
    x="day",
    order=["Thur", "Fri", "Sat", "Sun"],
    hue="time",
    palette="pastel"
)
plt.title("Conteo de visitas por día")
plt.show()

Trabajar con valores nulos

Seaborn ignora automáticamente los valores nulos (NaN) en la mayoría de las funciones, mostrando solo los datos disponibles. Sin embargo, es importante ser consciente de cómo afectan las estadísticas calculadas:

# El dataset penguins contiene valores nulos
penguins = sns.load_dataset("penguins")
print(f"Valores nulos por columna:")
print(penguins.isnull().sum())

# Seaborn maneja los nulos automáticamente
sns.histplot(data=penguins, x="bill_length_mm", hue="species", kde=True)
plt.title("Distribución del largo del pico (con nulos ignorados)")
plt.show()

# Para visualizar qué datos faltan
fig, ax = plt.subplots(figsize=(10, 4))
sns.heatmap(penguins.isnull(), cbar=False, yticklabels=False, cmap="viridis", ax=ax)
ax.set_title("Mapa de valores nulos en el dataset penguins")
plt.show()

Datos agrupados con groupby

Seaborn puede recibir el resultado de operaciones groupby de Pandas o datos previamente agregados:

# Calcular estadísticas agregadas antes de visualizar
import numpy as np

ventas_por_dia = (
    tips.groupby("day")
    .agg(
        importe_medio=("total_bill", "mean"),
        propina_media=("tip", "mean"),
        num_cuentas=("total_bill", "count")
    )
    .reset_index()
)

print(ventas_por_dia)

# Visualizar datos ya agregados
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

sns.barplot(
    data=ventas_por_dia,
    x="day",
    y="importe_medio",
    order=["Thur", "Fri", "Sat", "Sun"],
    palette="Blues_d",
    ax=axes[0]
)
axes[0].set_title("Importe medio por día")

sns.scatterplot(
    data=ventas_por_dia,
    x="importe_medio",
    y="propina_media",
    size="num_cuentas",
    sizes=(100, 500),
    ax=axes[1]
)
axes[1].set_title("Importe medio vs propina media")

plt.tight_layout()
plt.show()

Datos de series temporales

Para datos temporales, Seaborn funciona directamente con columnas de tipo datetime de Pandas:

import numpy as np

rng = np.random.default_rng(seed=42)

# Crear un DataFrame de ventas diarias
fechas = pd.date_range(start="2025-01-01", end="2025-12-31", freq="D")
ventas_diarias = pd.DataFrame({
    "fecha": fechas,
    "ventas": rng.integers(50, 300, size=len(fechas)) + np.sin(np.arange(len(fechas)) / 30) * 50,
    "canal": rng.choice(["Online", "Tienda"], size=len(fechas))
})

sns.lineplot(
    data=ventas_diarias,
    x="fecha",
    y="ventas",
    hue="canal",
    errorbar=None
)
plt.title("Ventas diarias por canal en 2025")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

Resumen: buenas prácticas con datos en Seaborn

  • Usa formato long-form siempre que sea posible: una observación por fila, una variable por columna.
  • Define tipos categóricos en Pandas cuando el orden de las categorías importa.
  • No extraigas arrays manualmente: pasa el DataFrame completo y referencia las columnas por nombre.
  • Comprueba los nulos antes de visualizar para entender su impacto en las estadísticas.
  • Transforma con melt/stack cuando tus datos originales estén en formato wide-form.
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Seaborn es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Seaborn

Explora más contenido relacionado con Seaborn y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Distinguir entre datos en formato long-form y wide-form. Transformar datos wide-form a long-form con pandas melt y stack. Comprender cómo Seaborn infiere las variables estéticas de los DataFrames. Usar datos agrupados y transformados directamente en las funciones de Seaborn. Trabajar con datos con valores nulos y tipos de datos categóricos.