patchwork para combinar gráficos

r
visualizacion
ggplot2
El paquete que combina varios ggplots en una sola figura. Sintaxis con + y /, plot_layout() para grids, & para temas compartidos y plot_annotation() para títulos globales.

¿Qué es patchwork?

patchwork es el paquete que añade a ggplot2 algo que la librería base no hace bien: combinar varios gráficos en una sola figura. Existieron precursores (gridExtra, cowplot) pero patchwork se ha convertido en el estándar moderno gracias a una sintaxis casi mágica.

install.packages("patchwork")
library(ggplot2)
library(patchwork)
library(palmerpenguins)

Donde antes había que pelearse con grid.arrange() y argumentos opacos, ahora basta con sumar gráficos.

La sintaxis básica: + y /

Tres operadores:

  • p1 + p2: coloca los gráficos uno al lado del otro (horizontal).
  • p1 / p2: uno sobre otro (vertical).
  • p1 | p2: sinónimo de + (horizontal).
p1 <- ggplot(penguins, aes(bill_length_mm, flipper_length_mm, color = species)) +
  geom_point()

p2 <- ggplot(penguins, aes(species, body_mass_g, fill = species)) +
  geom_boxplot()

p3 <- ggplot(penguins, aes(flipper_length_mm)) +
  geom_density(aes(fill = species), alpha = 0.5)

# Horizontal
p1 + p2

# Vertical
p1 / p2

# Combinado: el par horizontal sobre p3
(p1 + p2) / p3

Los paréntesis funcionan como esperarías: (p1 + p2) / p3 apila el par horizontal sobre p3. La sintaxis se compone como ecuaciones.

plot_layout() para control fino

Cuando quieres especificar exactamente cuántas filas/columnas o qué ratios:

p1 + p2 + p3 + p4 +
  plot_layout(ncol = 2)

# Ratios — primer gráfico el doble de ancho que el segundo
p1 + p2 +
  plot_layout(widths = c(2, 1))

# Lo mismo para alturas
p1 / p2 +
  plot_layout(heights = c(1, 2))

Para layouts complejos en cuadrícula, hay una notación de áreas con letras:

layout <- "
AABB
AACC
"

p1 + p2 + p3 +
  plot_layout(design = layout)

Cada letra representa una “celda”. Los gráficos se asignan en orden (A = p1, B = p2, C = p3). Esto permite layouts asimétricos sin pelearse con coordenadas.

& para temas y aesthetics compartidos

Aquí está la magia. Si quieres aplicar un theme a todos los gráficos de la composición:

(p1 + p2 + p3) & theme_minimal()

El operador & “broadcastea” la operación a cada subgráfico. Útil para componer cambios:

(p1 + p2) &
  theme_minimal() &
  scale_color_viridis_d() &
  theme(legend.position = "bottom")

Sin &, tendrías que añadir cada theme a cada gráfico antes de componerlos.

plot_annotation() para títulos globales

Cuando quieres un título y subtítulo para toda la figura, no para cada subgráfico:

(p1 + p2 + p3) +
  plot_annotation(
    title    = "Pingüinos del archipiélago de Palmer",
    subtitle = "Tres aspectos de la variabilidad morfológica",
    caption  = "Fuente: palmerpenguins"
  )

Y para etiquetar subgráficos con (A), (B), (C):

(p1 + p2 + p3) +
  plot_annotation(tag_levels = "A")

tag_levels = "A" numera con letras mayúsculas. "a" con minúsculas. "1" con números. "i" con romanos. La estética habitual en papers científicos.

Recoger leyendas duplicadas

Por defecto, si tres subgráficos comparten una leyenda (por ejemplo, todos coloreados por species), patchwork muestra tres copias de la leyenda. Para colapsarlas:

(p1 + p2 + p3) +
  plot_layout(guides = "collect") &
  theme(legend.position = "bottom")

guides = "collect" recoge las leyendas duplicadas y muestra una sola. Casi siempre es lo que quieres en figuras de presentación.

Trampas habituales

  • Olvidar library(patchwork) antes de usar + entre ggplots. Sin cargarlo, p1 + p2 da error porque ggplot2 no sabe qué hacer.
  • p1 + theme(...) vs (p1 + p2) & theme(...). El primero modifica p1. El segundo aplica el theme a todos los subgráficos. La distinción + vs & es la clave operativa.
  • Demasiados subgráficos. Más de 6 paneles en una figura empieza a parecer un póster lleno de letra pequeña. Si necesitas comparar muchos grupos, facet_wrap es probablemente mejor que patchwork.
  • plot_layout(guides = "collect") que no colapsa. Las leyendas se colapsan solo si son idénticas (mismo nombre, mismas categorías). Si una usa color = species y otra fill = species, son leyendas distintas. Unifica el aesthetic antes de colectar.

En la siguiente entrega

Has aprendido a componer gráficos. Queda el último componente que separa visualización editorial de visualización amateur: el color. Vemos paletas accesibles (viridis y por qué), cómo testar daltonismo en tus gráficos y cómo construir una paleta de marca propia. Es lo siguiente.