6. Gráficos multivariados

En esta sección verás tres utilidades clave para explorar relaciones multivariadas:

  • pairplot: explora todas las relaciones bivariadas entre variables numéricas, con histogramas/KDE en la diagonal.
  • jointplot: relación entre dos variables con distribuciones marginales (ejes X/Y).
  • lmplot: regresión lineal (simple o por subgrupos) con intervalos de confianza.

Todos los ejemplos incluyen imports y set_theme para copiar/pegar y ejecutar (Seaborn ≥ 0.12/0.13).

6.1 pairplot: explorar relaciones entre todas las variables numéricas

pairplot arma una grilla de gráficos bivariados para cada par de variables numéricas y muestra, en la diagonal, la distribución de cada una (histograma o KDE). Es el “primer vistazo” clásico para detectar correlaciones, no linealidades u outliers.

A) pairplot básico (dataset Iris)

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

iris = sns.load_dataset("iris")
g = sns.pairplot(data=iris)
g.fig.suptitle("Iris – Pairplot básico", y=1.02)
plt.show()

B) pairplot con hue y diagonal KDE

hue colorea por categoría (p. ej., especie).

diag_kind="kde" usa densidades suavizadas en la diagonal.

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

iris = sns.load_dataset("iris")

g = sns.pairplot(
    data=iris,
    hue="species",
    diag_kind="kde",        # "hist" (default) o "kde"
    corner=False,           # True mostraría solo triángulo inferior
    plot_kws={"alpha": 0.7, "s": 40}  # kwargs para los scatter de la grilla
)
g.fig.suptitle("Iris – Pairplot por especie (diagonal KDE)", y=1.02)
plt.show()

C) pairplot solo con columnas seleccionadas + corner=True

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

iris = sns.load_dataset("iris")
cols = ["sepal_length", "sepal_width", "petal_length", "petal_width"]

g = sns.pairplot(
    data=iris[cols],
    corner=True,        # muestra solo triángulo inferior
    diag_kind="hist"
)
g.fig.suptitle("Iris – Pairplot (solo columnas seleccionadas, corner=True)", y=1.02)
plt.show()
Tips (pairplot)
  • Si hay muchas columnas, el gráfico puede ser pesado; seleccioná variables clave.
  • corner=True mejora la legibilidad.
  • Ajustá plot_kws para controlar opacidad/tamaño de puntos.

6.2 jointplot: relación entre dos variables con distribuciones marginales

jointplot dibuja un gráfico central (relación X–Y) y, en los márgenes, las distribuciones de X y Y. Soporta varios kind: "scatter", "kde", "hist", "hex", "reg".

A) jointplot con dispersión + histogramas marginales

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

penguins = sns.load_dataset("penguins").dropna(subset=["bill_length_mm", "bill_depth_mm"])

g = sns.jointplot(
    data=penguins,
    x="bill_length_mm",
    y="bill_depth_mm",
    kind="scatter",       # "scatter" por defecto
    height=5,             # tamaño de la figura
    space=0.1             # espacio entre centro y márgenes
)
g.fig.suptitle("Penguins – Jointplot (scatter + histogramas)", y=1.02)
plt.show()

B) jointplot con KDE 2D + KDE marginal (suavizado)

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

penguins = sns.load_dataset("penguins").dropna(subset=["bill_length_mm", "bill_depth_mm"])

g = sns.jointplot(
    data=penguins,
    x="bill_length_mm",
    y="bill_depth_mm",
    kind="kde",          # densidad 2D en el centro + KDE marginal
    fill=True,           # relleno en KDE
    thresh=0.05,         # umbral de isolíneas
    height=5
)
g.fig.suptitle("Penguins – Jointplot KDE (2D + marginal)", y=1.02)
plt.show()

C) jointplot con hexbin (datos densos) o regresión (kind="reg")

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

tips = sns.load_dataset("tips")

# Hexbin (ideal para datos densos/solapados)
g1 = sns.jointplot(
    data=tips,
    x="total_bill", y="tip",
    kind="hex",
    height=5, gridsize=20,  # hexágonos
    cmap="mako"
)
g1.fig.suptitle("Tips – Jointplot HEX", y=1.02)

# Regresión simple (línea + bandas)
g2 = sns.jointplot(
    data=tips,
    x="total_bill", y="tip",
    kind="reg",           # scatter + recta + bandas
    height=5
)
g2.fig.suptitle("Tips – Jointplot REG (con tendencia)", y=1.02)

plt.show()
Tips (jointplot)
  • Elegí kind según el volumen y la distribución:
    • pocos puntos → scatter / reg
    • muchos puntos → hex
    • “forma” continua → kde
  • Ajustá height y space para mejorar la lectura.

6.3 lmplot: regresión lineal con intervalos de confianza

lmplot es una función de nivel figura (como relplot/catplot) que facilita:

  • Ajustar regresiones lineales (simples) por subgrupos con facetas.
  • Mostrar intervalos de confianza automáticos.
  • Dividir por hue, o por columnas/filas (col, row).

A) Regresión simple con bandas de confianza

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

tips = sns.load_dataset("tips")

g = sns.lmplot(
    data=tips,
    x="total_bill", y="tip",
    height=4, aspect=1.2,      # tamaño (figura de alto nivel)
    ci=95                      # nivel de confianza; None para ocultar
)
g.fig.suptitle("Regresión lineal simple (lmplot)", y=1.02)
plt.show()

B) Regresión por subgrupos con hue y estilos

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

tips = sns.load_dataset("tips")

g = sns.lmplot(
    data=tips,
    x="total_bill", y="tip",
    hue="sex",            # una recta por sexo
    markers=["o", "s"],   # estilos de puntos por grupo
    palette="deep",
    height=4, aspect=1.2
)
g.fig.suptitle("Regresión por sexo (rectas separadas)", y=1.02)
plt.show()

C) Facetas con col/row + hue (tres dimensiones categóricas)

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")

tips = sns.load_dataset("tips")

g = sns.lmplot(
    data=tips,
    x="total_bill", y="tip",
    hue="sex",            # color por sexo
    col="time",           # Lunch vs Dinner en columnas
    row="smoker",         # filas por fumador/no fumador
    height=3, aspect=1.2
)
g.set_axis_labels("Total bill", "Tip")
g.set_titles("time={col_name} | smoker={row_name}")
g.fig.suptitle("lmplot con facetas: time × smoker, hue=sex", y=1.03)
plt.show()

D) Desactivar ajuste o usar ajuste robusto / polinomial

fit_reg=False en versiones antiguas; en modernas es mejor usar order/robust a través de sns.regplot o Seaborn Objects.

Para polinomios o ajustes robustos, hoy es más flexible usar Seaborn Objects:

import seaborn as sns
import seaborn.objects as so
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", context="notebook")
tips = sns.load_dataset("tips")

(
    so.Plot(tips, x="total_bill", y="tip", color="sex")
      .add(so.Dots(alpha=0.7))
      .add(so.Line(), so.PolyFit(order=2))   # ajuste polinomial grado 2
      .layout(size=(6, 4))
).show()
Tips (lmplot)
  • lmplot re-crea la figura cada vez (nivel figura). Para control fino dentro de ejes existentes, usá sns.regplot o Seaborn Objects.
  • Si hay mucha variación por subgrupo, limitá categorías o usá facetas para legibilidad.

6.4 Buenas prácticas (multivariado)

  • Empezá con pairplot para detectar relaciones obvias y outliers.
  • Para dos variables con contexto de distribución, jointplot es más comunicativo que un scatter plano.
  • Para tendencias y segmentación, lmplot simplifica ajustes por grupo y facetas.
  • No satures un solo gráfico con demasiadas categorías; preferí facetas (col/row).
  • Ajustá opacidad (alpha) y tamaño de puntos (s) para reducir solapamiento.
  • Recordá que la significancia de una tendencia requiere validación estadística posterior (no solo “línea bonita”).

Mini-checklist

  • ¿Visión global de varias numéricas → pairplot (con hue si aplica).
  • Dos variables + marginals → jointplot (scatter, kde, hex, reg).
  • Tendencias por grupo → lmplot (hue, col, row, ci).
  • ¿Ajuste polinomial/robusto? → Seaborn Objects + so.PolyFit.