p1 <- ggplot(mpg) +
geom_point(aes(x = displ, y = hwy))
p2 <- ggplot(mpg) +
geom_bar(aes(x = as.character(year), fill = drv), position = "dodge") +
labs(x = "year")
p3 <- ggplot(mpg) +
geom_density(aes(x = hwy, fill = drv), colour = NA) +
facet_grid(rows = vars(drv))
p4 <- ggplot(mpg) +
stat_summary(aes(x = drv, y = hwy, fill = drv), geom = "col", fun.data = mean_se) +
stat_summary(aes(x = drv, y = hwy), geom = "errorbar", fun.data = mean_se, width = 0.5)
9 Organizar gráficas
You are reading the work-in-progress third edition of the ggplot2 book. This chapter is currently a dumping ground for ideas, and we don’t recommend reading it.
La gramática presentada en ggplot2 se ocupa de la creación de gráficos únicos. Si bien el sistema de facetas proporciona los medios para producir varias subgráficas, todas ellas forman parte de la misma visualización principal y comparten capas, datos y escalas. Sin embargo, a menudo es necesario utilizar múltiples gráficas dispares para contar una historia o presentar un argumento. Por supuesto, estos pueden crearse individualmente y ensamblarse en un programa de diseño, pero es beneficioso hacerlo en código para evitar un trabajo manual lento y no reproducible. Una variedad de paquetes han estado a la altura de las circunstancias y ofrecen diferentes enfoques para organizar gráficas separadas. Si bien este capítulo se centrará en el paquete patchwork, es posible que también encuentre algunas de las mismas funcionalidades en los paquetes cowplot, gridExtra y ggpubr.
Este capítulo se dividirá en dos partes. El primero se ocupará de organizar las gráficas una al lado de la otra sin que se superpongan, mientras que el segundo se ocupará de organizar las gráficas una encima de la otra. Si bien estos dos escenarios no son necesariamente opuestos entre sí, el primero a menudo se beneficiará de una funcionalidad que tiene poco sentido en el segundo, p.e. alineación de las regiones de trazado.
9.1 Disposición de gráficas una al lado de la otra
A menudo, uno quiere mostrar dos o más gráficas una al lado de la otra para mostrar diferentes aspectos de la misma historia de una manera convincente. Este es el escenario para el que se creó patchwork. En esencia, patchwork es un paquete que extiende el uso del operador +
de ggplot2 para trabajar entre múltiples gráficos, así como también agrega operadores adicionales para composiciones especializadas y trabajar con composiciones de gráficos.
Como ejemplo del uso más básico de patchwork, usaremos los siguientes 4 gráficos del conjunto de datos mpg
El uso más simple de patchwork es usar +
para sumar gráficos, creando así un conjunto de gráficos para mostrar juntos:
+
no especifica ningún diseño específico, solo que los gráficos deben mostrarse juntos. En ausencia de un diseño, el mismo algoritmo que gobierna el número de filas y columnas en facet_wrap()
decidirá el número de filas y columnas. Esto significa que sumar 3 gráficas creará una cuadrícula de 1x3, mientras que sumar 4 gráficas creará una cuadrícula de 2x2.
p1 + p2 + p3 + p4
Como se puede observar en los dos ejemplos anteriores, el patchwork se encarga de alinear las diferentes partes de las gráficas entre sí. Puede ver que todas las regiones de trazado están alineadas, incluso en presencia de facetado. Además, puede ver que los títulos del eje y en los dos gráficos más a la izquierda están alineados a pesar de que el texto del eje en el gráfico inferior izquierdo es más ancho.
9.1.1 Tomando el control del diseño
A menudo, la cuadrícula creada automáticamente no es la que usted desea y, por supuesto, es posible controlarla. La forma más directa y poderosa de hacer esto es agregar una especificación plot_layout()
al gráfico:
p1 + p2 + p3 + plot_layout(ncol = 2)
Un escenario común es querer forzar una sola fila o columna. patchwork proporciona dos operadores, |
y /
respectivamente, para facilitar esto (debajo del capó, simplemente establecen el número de filas o columnas en el diseño en 1).
p1 / p2
# Básicamente lo mismo que usar `+` pero la intención es más clara.
p3 | p4
patchwork permite anidar diseños, lo que significa que es posible crear diseños muy complejos utilizando sólo estos dos operadores.
p3 | (p2 / (p1 | p4))
Alternativamente, para diseños muy complejos, es posible especificar diseños no tabulares con una representación textual en el argumento design
en plot_layout()
.
layout <- "
AAB
C#B
CDD
"
p1 + p2 + p3 + p4 + plot_layout(design = layout)
Como ha sido evidente en las últimas gráficas, la leyenda a menudo se vuelve redundante entre gráficas. Si bien es posible eliminar la leyenda en todos los gráficos menos uno antes de ensamblarlos, el mosaico proporciona algo más fácil para el caso común:
p1 + p2 + p3 + plot_layout(ncol = 2, guides = "collect")
La elección de recopilar guías tomará todas las guías y las reunirá en la posición regida por el tema global. Además, eliminará cualquier guía duplicada y dejará solo guías únicas en la gráfica. La detección de duplicaciones analiza la apariencia de la guía y no la escala subyacente de la que proviene. Por lo tanto, sólo eliminará las guías que sean exactamente iguales. Si desea optimizar el uso del espacio colocando guías en un área vacía del diseño, puede especificar un área de trazado para las guías recopiladas:
p1 + p2 + p3 + guide_area() + plot_layout(ncol = 2, guides = "collect")
9.1.2 Modificando subgráficas
Uno de los principios del patchwork es que los gráficos permanecen como objetos estándar de ggplot hasta que se renderizan. Esto significa que son susceptibles de modificación una vez ensamblados. Los gráficos específicos se pueden recuperar y configurar con la indexación [[]]
:
p12 <- p1 + p2
p12[[2]] <- p12[[2]] + theme_light()
p12
Sin embargo, a menudo es necesario modificar todas las subgráficas a la vez, por ejemplo. darles un tema común. patchwork proporciona el &
para este escenario:
p1 + p4 & theme_minimal()
Esto también se puede utilizar para darle a las gráficas un eje común si comparten la misma estética en ese eje:
p1 + p4 & scale_y_continuous(limits = c(0, 45))
9.1.3 Agregar anotaciones
Una vez ensambladas las gráficas, pasan a formar una sola unidad. Esto también significa que los títulos, subtítulos y subtítulos a menudo pertenecerán al conjunto completo y no a gráficas individuales. Se pueden agregar títulos, etc. a los gráficos de mosaico usando la función plot_annotation()
.
p34 <- p3 + p4 + plot_annotation(
title = "Una mirada más cercana al efecto de la transmisión en los automóviles",
caption = "Fuente: conjunto de datos de mpg en ggplot2"
)
p34
Los títulos formateados según la especificación del tema en la llamada plot_annotation()
.
p34 + plot_annotation(theme = theme_gray(base_family = "mono"))
Como el tema global a menudo sigue el tema de las subgráficas, usar &
junto con un objeto de tema modificará el tema global así como los temas de las subgráficas.
p34 & theme_gray(base_family = "mono")
Otro tipo de anotación, conocida especialmente en la literatura científica, consiste en agregar etiquetas a cada subgráfica que luego se utilizarán para identificarlas en el texto y el título. ggplot2 tiene el elemento tag
exactamente para esto y patchwork ofrece funcionalidad para configurarlo automáticamente usando el argumento tag_levels
. Puede generar niveles automáticos en caracteres latinos, números arábigos o números romanos.
p123 <- p1 | (p2 / p3)
p123 + plot_annotation(tag_levels = "I") # Números romanos en mayúsculas
Una característica adicional es que es posible utilizar el anidamiento para definir nuevos niveles de etiquetado:
p123[[2]] <- p123[[2]] + plot_layout(tag_level = "new")
p123 + plot_annotation(tag_levels = c("I", "a"))
Como puede verse, el patchwork ofrece una amplia gama de posibilidades a la hora de organizar gráficas, y la API escala con el nivel de complejidad del ensamblaje, desde simplemente usar +
para colocar múltiples gráficas en la misma área, hasta usar anidamiento. , diseños y anotaciones para crear diseños personalizados avanzados.
9.2 Organizar gráficas una encima de la otra.
Si bien gran parte de la funcionalidad del patchwork se refiere a alinear trazados en una cuadrícula, también permite hacer inserciones, es decir, pequeños trazados colocados encima de otro trazado. La funcionalidad para esto está incluida en la función inset_element()
que sirve para marcar el gráfico dado como un recuadro que se colocará en el gráfico anterior, además de registrar la ubicación deseada, etc. El uso básico es el siguiente:
p1 + inset_element(p2, left = 0.5, bottom = 0.4, right = 0.9, top = 0.95)
La posición se especifica mediante la ubicación izquierda, derecha, superior e inferior del recuadro. El valor predeterminado es usar unidades npc
que van de 0 a 1 en el área dada, pero se puede usar cualquier grid::unit()
brindándolas explícitamente. La ubicación está establecida de forma predeterminada en el área del panel, pero esto se puede cambiar con el argumento align_to
. Combinando todo esto podemos colocar un recuadro exactamente a 15 mm de la esquina superior derecha así:
p1 +
inset_element(
p2,
left = 0.4,
bottom = 0.4,
right = unit(1, "npc") - unit(15, "mm"),
top = unit(1, "npc") - unit(15, "mm"),
align_to = "full"
)
los recuadros no se limitan a ggplots. Se puede utilizar cualquier gráfico compatible con wrap_elements()
, incluidos los mosaicos:
p24 <- p2 / p4 + plot_layout(guides = "collect")
p1 + inset_element(p24, left = 0.5, bottom = 0.05, right = 0.95, top = 0.9)
Una característica interesante de los recuadros es que se comportan como subgráficas estándar de mosaico hasta que se renderizan. Esto significa que son susceptibles de modificaciones después del montaje, p.e. usando &
:
p12 <- p1 + inset_element(p2, left = 0.5, bottom = 0.5, right = 0.9, top = 0.95)
p12 & theme_bw()
Y el etiquetado automático también funciona como se esperaba:
p12 + plot_annotation(tag_levels = "A")
9.3 Terminando
Este capítulo ha ofrecido una breve descripción de algunas de las posibilidades de composición que ofrece el patchwork, pero de ninguna manera es exhaustivo. Patchwork proporciona soporte para algo más que ggplots y también le permite combinar elementos gráficos de cuadrícula y base con sus gráficos si es necesario. También permite diseños aún más complejos utilizando el constructor area()
en lugar de la representación textual que se muestra aquí. Todas estas funcionalidades y muchas más están cubiertas en las diferentes guías disponibles en su sitio web: https://patchwork.data-imaginist.com