r - guia - qgis manual
Organiza n ggplots en forma de matriz triangular inferior (5)
Aquí hay un enfoque bastante sencillo, que no debería ser demasiado difícil de generalizar:
library(gridExtra) ## for grid.arrange()
ng <- nullGrob()
grid.arrange(plots[[1]], ng, ng,
plots[[2]], plots[[3]], ng,
plots[[4]], plots[[5]], plots[[6]])
Tengo n ggplot objetos que siempre tendrán el número correcto para hacer un triángulo inferior de una matriz (sin diagonales). ¿Cómo puedo organizarlos en este orden?
1
2 3
4 5 6
7 8 9 10
para formar una cuadrícula (n = 10 aquí)?
Aquí hay datos para hacer n parcelas y cómo me gustaría que tuviera n = 6.
n <- sample(1:4, 1)
N <- sum(n:1)
library(ggplot2)
theplot <- ggplot(mtcars, aes(mpg, hp)) + geom_point()
plots <- lapply(1:N, function(i) theplot)
plots <- mapply(function(x, y) x + ggtitle(y), plots,
paste("PLOT", seq_along(plots)), SIMPLIFY=FALSE)
Sospecho que gridExtra
puede ser útil aquí, pero hay paneles en blanco. Estoy abierto a la base o agregar ideas de paquetes.
Y esta es la solución más general ...
rows <- 1:3
get.row <- function(i){
if (i==1) return(arrangeGrob(plots[[1]],ncol=length(rows)))
start=sum(seq[1:(i-1)])+1
end <- start+seq[i]-1
do.call(arrangeGrob,c(lapply(start:end,function(i)plots[[i]]),ncol=length(rows)))
}
grid.newpage()
grid.arrange(do.call(arrangeGrob,c(lapply(1:length(rows),get.row),nrow=length(rows))))
Otra generalización basada en la respuesta de Josh
trianglePlotGrid <- function(plots){
#take a list of plots and returns a single plot where the elements in the list arranged in a triangular grid
#plots should be a list of 1 or 3 or 6... plots to be arranged in a trianglular structure with 1 plot in the top row
ncols <- (-1 + sqrt(1 + 8*length(plots)))/2
i = 0; j = 0
grobs <- list()
for(p in plots){
grobs[[length(grobs)+1]] <- p
j = (j+1) %% ncols
while(j > i){
grobs[[length(grobs)+1]] <- nullGrob()
j = (j+1) %% ncols
}
if(j == 0) i = i + 1
}
do.call("grid.arrange", c(grobs, ncol=ncols))
}
df <- data.frame(x=c(1,2), y=c(1,2))
p <- ggplot(df, aes(x=x, y=y))+geom_point()
plist <- list(p, p, p, p, p, p)
trianglePlotGrid(plist)
Yo era un fanático de wq::layOut
para organizar ggplots cuando grid.arrange
parece demasiado complicado (aunque Josh muestra que funciona bien aquí). Si usa un dispositivo nuevo, no debe preocuparse por los agujeros.
layOut
se eliminó del paquete wq
, por lo que wq
el código aquí, renombrado a lay_out
. Está en la parte inferior, después de los ejemplos de uso.
lay_out(list(plots[[1]], 1, 1), # each arg is list(plot, row(s), column(s))
list(plots[[2]], 2, 1),
list(plots[[3]], 2, 2))
Su principal fortaleza es cuando tienes parcelas de diferentes tamaños.
lay_out(list(plots[[1]], 1, 1:3),
list(plots[[2]], 2, 1),
list(plots[[3]], 2, 2),
list(plots[[4]], 3, 1:2),
list(plots[[5]], 2:3, 3))
Creo que cualquier cosa que se pueda hacer con layOut
se puede hacer con grid.arrange
anidado y arrangeGrob
llamadas de grupo, pero a menudo es más fácil pensar de esta manera.
#'' Arranging ggplots
#''
#'' Provides a /code{layout}-like interface for arranging ggplots of different
#'' sizes.
#''
#'' @param ... Each argument should be of the form /code{list(plot, rows,
#'' columns)}, where /code{plot} is a ggplot (or similar), and /code{rows} and
#'' /code{columns} are consecutive sequences indicating the row and column
#'' numbers for /code{plot} to span.
#''
#'' @author Alan D. Jassby and James E. Cloern (originally from the /code{wq}
#'' package).
#''
#'' @examples
#'' /dontrun{
#'' gg <- ggplot(mtcars, aes(x = hp, y = mpg)) + geom_point()
#'' layOut(list(gg, 1:2, 1:3),
#'' list(gg, 3, 1:2),
#'' list(gg, 3, 3))
#'' }
#''
#'' @export
lay_out <- function(...) {
x <- list(...)
n <- max(sapply(x, function(x) max(x[[2]])))
p <- max(sapply(x, function(x) max(x[[3]])))
grid::pushViewport(grid::viewport(layout = grid::grid.layout(n, p)))
for (i in seq_len(length(x))) {
print(x[[i]][[1]],
vp = grid::viewport(layout.pos.row = x[[i]][[2]],
layout.pos.col = x[[i]][[3]]))
}
}