Alinee las áreas de trazado en ggplot

Estoy tratando de usar grid.arrange para mostrar múltiples gráficos en la misma página generada por ggplot. Las plots usan los mismos datos x pero con diferentes variables y. Las ttwigs salen con diferentes dimensiones debido a que los datos y tienen diferentes escalas.

He intentado usar varias opciones de temas dentro de ggplot2 para cambiar el tamaño de la gráfica y mover la etiqueta del eje y, pero ninguno ha funcionado para alinear las gráficas. Quiero que las ttwigs se organicen en un cuadrado de 2 x 2 para que cada ttwig tenga el mismo tamaño y los ejes x se alineen.

Aquí hay algunos datos de prueba:

A <- c(1,5,6,7,9) B <- c(10,56,64,86,98) C <- c(2001,3333,5678,4345,5345) D <- c(13446,20336,24333,34345,42345) L <- c(20,34,45,55,67) M <- data.frame(L, A, B, C, D) 

Y el código que estoy usando para trazar:

 x1 <- ggplot(M, aes(L, A,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') x2 <- ggplot(M, aes(L, B,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') x3 <- ggplot(M, aes(L, C,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') x4 <- ggplot(M, aes(L, D,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') grid.arrange(x1,x2,x3,x4,nrow=2) 

Si ejecuta este código, verá que los dos trazados inferiores tienen un área de trazado menor debido a la mayor longitud de las unidades de eje y.

¿Cómo hago que las ventanas de la ttwig real sean las mismas?

Yo usaría facetas para este problema:

 library(reshape2) dat <- melt(M,"L") # When in doubt, melt! ggplot(dat, aes(L,value)) + geom_point() + stat_smooth(method="lm") + facet_wrap(~variable,ncol=2,scales="free") 

Ejemplo

Nota: El profano puede pasar por alto que las escalas son diferentes entre las facetas.

Editar

Las soluciones más simples son: 1) usar el paquete cowplot (ver respuesta aquí); o 2) use un paquete de egg disponible en github.

 # devtools::install_github("baptiste/egg") library(egg) library(grid) g = ggarrange(x1, x2, x3, x4, ncol = 2) grid.newpage() grid.draw(g) 

Original

Edición menor: Actualización de código.

Si desea conservar las tags de los ejes, entonces con un toque de violín y un código de préstamo de aquí , esto hace el trabajo.

 library(ggplot2) library(gtable) library(grid) library(gridExtra) # Get the widths gA <- ggplotGrob(x1) gB <- ggplotGrob(x2) gC <- ggplotGrob(x3) gD <- ggplotGrob(x4) maxWidth = unit.pmax(gA$widths[2:3], gB$widths[2:3], gC$widths[2:3], gD$widths[2:3]) # Set the widths gA$widths[2:3] <- maxWidth gB$widths[2:3] <- maxWidth gC$widths[2:3] <- maxWidth gD$widths[2:3] <- maxWidth # Arrange the four charts grid.arrange(gA, gB, gC, gD, nrow=2) 

enter image description here

SOLUCIONES ALTERNATIVAS: Hay funciones de rbind y cbind en el paquete de gtable para combinar grobs en un grupo. Para los gráficos aquí, los anchos se deben establecer usando size = "max" , pero la versión de CRAN de gtable arroja un error.

Una opción es examinar el gráfico grid.arrange y luego usar size = "first" o size = "last" `options:

 # Get the ggplot grobs gA <- ggplotGrob(x1) gB <- ggplotGrob(x2) gC <- ggplotGrob(x3) gD <- ggplotGrob(x4) # Arrange the four charts grid.arrange(gA, gB, gC, gD, nrow=2) # Combine the plots g = cbind(rbind(gA, gC, size = "last"), rbind(gB, gD, size = "last"), size = "first") # draw it grid.newpage() grid.draw(g) 

Una segunda opción es bind funciones del paquete gridExtra .

 # Get the ggplot grobs gA <- ggplotGrob(x1) gB <- ggplotGrob(x2) gC <- ggplotGrob(x3) gD <- ggplotGrob(x4) # Combine the plots g = cbind.gtable(rbind.gtable(gA, gC, size = "max"), rbind.gtable(gB, gD, size = "max"), size = "max") # Draw it grid.newpage() grid.draw(g) 

Ese es exactamente el tipo de problema por el que escribí el paquete cowplot . Se puede hacer en una línea en ese paquete:

 require(cowplot) # loads ggplot2 as dependency # re-create the four plots A <- c(1,5,6,7,9) B <- c(10,56,64,86,98) C <- c(2001,3333,5678,4345,5345) D <- c(13446,20336,24333,34345,42345) L <- c(20,34,45,55,67) M <- data.frame(L, A, B, C, D) x1 <- ggplot(M, aes(L, A,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') x2 <- ggplot(M, aes(L, B,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') x3 <- ggplot(M, aes(L, C,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') x4 <- ggplot(M, aes(L, D,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm') # arrange into grid and align plot_grid(x1, x2, x3, x4, align='vh') 

Este es el resultado: enter image description here (Tenga en cuenta que cowplot cambia el tema predeterminado ggplot2. Puede recuperar el gris si lo desea).

Como característica de bonificación, también puede agregar tags de trazado en la esquina superior izquierda de cada gráfico:

 plot_grid(x1, x2, x3, x4, align='vh', labels=c('A', 'B', 'C', 'D')) 

Resultado: enter image description here

Utilizo la opción de labels en prácticamente todos los gráficos de varias partes que hago.

Patchwork es un nuevo paquete que hace que sea muy fácil formatear y diseñar múltiples ggplots. Una de las mejores cosas es que alinea las áreas de trazado automáticamente. Además, la syntax es realmente fácil.

 devtools::install_github("thomasp85/patchwork") library(patchwork) x1 + x2 + x3 + x4 + plot_layout(ncol = 2) 

enter image description here

Consulte la página de GitHub para obtener más ejemplos: https://github.com/thomasp85/patchwork

Si usa RMarkdown y teje a PDF, tengo un enfoque alternativo. Knitr ofrece la funcionalidad para trazar subfiguras cuando se crea un PDF, lo que le permite tener múltiples figuras en un gráfico, cada una con su propio título.

Para que esto funcione, cada gráfico debe mostrarse por separado. Al unir varias funciones del paquete cowplot , realicé la siguiente función que alinea las representaciones y las mantiene como objetos separados:

 plot_grid_split <- function(..., align = "hv", axis= "tblr"){ aligned_plots <- cowplot::align_plots(..., align=align, axis=axis) plots <- lapply(1:length(aligned_plots), function(x){ cowplot::ggdraw(aligned_plots[[x]]) }) invisible(capture.output(plots)) } 

Aquí hay un ejemplo, comparando el diseño normalmente versus el uso de la función:

 --- output: pdf_document header-includes: - \usepackage{subfig} --- ```{r} plot_grid_split <- function(..., align = "hv", axis= "tblr"){ aligned_plots <- cowplot::align_plots(..., align=align, axis=axis) plots <- lapply(1:length(aligned_plots), function(x){ cowplot::ggdraw(aligned_plots[[x]]) }) invisible(capture.output(plots)) } ``` ```{r fig-sub, fig.cap='Four Plots Not Aligned', fig.subcap=c('Plot One', 'Plot Two', 'Plot Three', 'Plot Four'), out.width='.49\\linewidth', fig.asp=1, fig.ncol = 2} library(ggplot2) plot <- ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) + geom_point() plot + labs(title = "A nice title") plot + labs(caption = "A sample caption") plot + theme(legend.position = "none") plot + theme(legend.position = "top") ``` ```{r fig-sub-2, fig.cap='Four Plots Aligned', fig.subcap=c('Plot One', 'Plot Two', 'Plot Three', 'Plot Four'), out.width='.49\\linewidth', fig.asp=1, fig.ncol = 2} x1 <- plot + labs(title = "A nice title") x2 <- plot + labs(caption = "A sample caption") x3 <- plot + theme(legend.position = "none") x4 <- plot + theme(legend.position = "top") plot_grid_split(x1, x2, x3, x4) ``` 

enter image description here

  • Puede obtener más información sobre las subfiguras en R en esta publicación .
  • Además, puede consultar las opciones de knitr para obtener más información sobre las opciones de fragmentos para las subfiguras: https://yihui.name/knitr/options/