Esta é uma postagem cruzada no grupo ggplot2 google
Minha situação é que estou trabalhando em uma função que produz um número arbitrário de gráficos (dependendo dos dados de entrada fornecidos pelo usuário). A função retorna uma lista de n gráficos, e eu gostaria de colocá-los em uma formação 2 x 2. Estou lutando com os problemas simultâneos de:
- Como posso permitir que a flexibilidade seja entregue a um número arbitrário (n) de parcelas?
- Como posso também especificar que quero eles dispostos 2 x 2
Minha estratégia atual usa grid.arrange
do gridExtra
pacote. Provavelmente não é o ideal, especialmente porque, e essa é a chave, não funciona totalmente . Aqui está meu código de amostra comentado, experimentando três 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 estou acostumado a fazer, humildemente me encolho no canto, aguardando ansiosamente o feedback sagaz de uma comunidade muito mais sábia do que eu. Especialmente se estou tornando isso mais difícil do que o necessário.
Respostas:
Você está quase lá! O problema é que
do.call
espera que seu args esteja em umlist
objeto nomeado . Você os colocou na lista, mas como cadeias de caracteres, não como itens nomeados da lista.Eu acho que isso deve funcionar:
como Ben e Joshua apontaram nos comentários, eu poderia ter atribuído nomes quando criei a lista:
ou
fonte
args.list <- list(x=x, y=y, z=x, nrow=2, ncol=2)
do.call
sucesso, seria necessário haver correspondência posicional exata.traceback()
informações muito melhores se usar argumentos nomeados.grid.arrange()
é a...
correspondência posicional, é provavelmente irrelevante. Cada entrada deve ser um objeto de grade (com ou sem nome), um parâmetro nomeado paragrid.layout
ou um parâmetro nomeado para os argumentos restantes.Tente isto,
fonte
ggsave("multipage.pdf", do.call(marrangeGrob, c(plots, list(nrow=2, ncol=2))))
Estou respondendo um pouco tarde, mas tropecei em uma solução no R Graphics Cookbook que faz algo muito semelhante usando uma função personalizada chamada
multiplot
. Talvez ajude outros que encontrarem esta questão. Também estou adicionando a resposta, pois a solução pode ser mais recente do que as outras respostas a esta pergunta.Vários gráficos em uma página (ggplot2)
Aqui está a função atual, embora use o link acima, pois o autor observou que ela foi atualizada para ggplot2 0.9.3, o que indica que pode mudar novamente.
Um cria objetos de enredo:
E então os passa para
multiplot
:fonte