Esto es una publicación cruzada en el grupo de google ggplot2
Mi situación es que estoy trabajando en una función que genera un número arbitrario de gráficos (dependiendo de los datos de entrada proporcionados por el usuario). La función devuelve una lista de n gráficos, y me gustaría colocar esos gráficos en una formación de 2 x 2. Estoy luchando con los problemas simultáneos de:
- ¿Cómo puedo permitir que la flexibilidad se entregue un número arbitrario (n) de parcelas?
- ¿Cómo puedo especificar también que los quiero distribuidos 2 x 2?
Mi estrategia actual utiliza grid.arrange
del gridExtra
paquete. Probablemente no sea óptimo, especialmente porque, y esto es clave, no funciona en absoluto . Aquí está mi código de muestra comentado, experimentando con tres gráficos:
library(ggplot2)
library(gridExtra)
x <- qplot(mpg, disp, data = mtcars)
y <- qplot(hp, wt, data = mtcars)
z <- qplot(qsec, wt, data = mtcars)
# A normal, plain-jane call to grid.arrange is fine for displaying all my plots
grid.arrange(x, y, z)
# But, for my purposes, I need a 2 x 2 layout. So the command below works acceptably.
grid.arrange(x, y, z, nrow = 2, ncol = 2)
# The problem is that the function I'm developing outputs a LIST of an arbitrary
# number plots, and I'd like to be able to plot every plot in the list on a 2 x 2
# laid-out page. I can at least plot a list of plots by constructing a do.call()
# expression, below. (Note: it totally even surprises me that this do.call expression
# DOES work. I'm astounded.)
plot.list <- list(x, y, z)
do.call(grid.arrange, plot.list)
# But now I need 2 x 2 pages. No problem, right? Since do.call() is taking a list of
# arguments, I'll just add my grid.layout arguments to the list. Since grid.arrange is
# supposed to pass layout arguments along to grid.layout anyway, this should work.
args.list <- c(plot.list, "nrow = 2", "ncol = 2")
# Except that the line below is going to fail, producing an "input must be grobs!"
# error
do.call(grid.arrange, args.list)
Como suelo hacer, me acurruco humildemente en un rincón, esperando ansiosamente los comentarios sagaces de una comunidad mucho más sabia que yo, especialmente si estoy haciendo esto más difícil de lo necesario.
Respuestas:
¡Ya casi estás ahí! El problema es que
do.call
espera que sus argumentos estén en unlist
objeto con nombre . Los ha puesto en la lista, pero como cadenas de caracteres, no como elementos de lista con nombre.Creo que esto debería funcionar:
como señalaron Ben y Joshua en los comentarios, podría haber asignado nombres cuando creé la lista:
o
fuente
args.list <- list(x=x, y=y, z=x, nrow=2, ncol=2)
do.call
para tener éxito, habría sido necesario una coincidencia posicional exacta.traceback()
información mucho mejores si utiliza argumentos con nombre.grid.arrange()
es...
concordancia posicional es probablemente irrelevante. Cada entrada debe ser un objeto de cuadrícula (con o sin nombre), un parámetro con nombregrid.layout
o un parámetro con nombre para los argumentos restantes.Prueba esto,
fuente
ggsave("multipage.pdf", do.call(marrangeGrob, c(plots, list(nrow=2, ncol=2))))
Estoy respondiendo un poco tarde, pero encontré una solución en R Graphics Cookbook que hace algo muy similar usando una función personalizada llamada
multiplot
. Quizás ayude a otros que encuentren esta pregunta. También estoy agregando la respuesta, ya que la solución puede ser más nueva que las otras respuestas a esta pregunta.Múltiples gráficos en una página (ggplot2)
Aquí está la función actual, aunque use el enlace anterior, ya que el autor señaló que se ha actualizado para ggplot2 0.9.3, lo que indica que puede cambiar nuevamente.
Uno crea objetos de la trama:
Y luego los pasa a
multiplot
:fuente