Como posso obter uma grade 'desequilibrada' de ggplots?

94

Com grid.arrange, posso organizar várias ggplotfiguras em uma grade para obter uma figura de vários painéis usando algo como:

library(ggplot2)
library(grid)
library(gridExtra)

gerar alguns gráficos ggplot2, então

plot5 <- grid.arrange(plot4, plot1, heights=c(3/4, 1/4), ncol=1, nrow=2)

Como posso obter um layout 'desequilibrado' de 2 colunas com um gráfico em toda a primeira coluna e três gráficos na segunda coluna? Eu brinquei com uma abordagem de 'grade de grades' tentando usar grid.arrangepara traçar uma grade (por exemplo plot5, acima) contra outra trama, mas obtive:

Erro em layGrob (..., as.table = as.table, clip = clip, main = main,: input deve ser grobs!

Atualizar:

Obrigado pelo conselho. Vou examinar viewportse grid. Nesse ínterim, graças a @DWin, a layOutfunção no pacote 'wq' funcionou muito bem para a figura de compilação em meu Sweavedocumento: insira a descrição da imagem aqui

Atualização 2:

O arrangeGrobcomando (como sugerido por @baptiste) também funciona bem e parece muito intuitivo - pelo menos foi fácil alterar a largura das duas colunas. Também tem a vantagem de não exigir o pacote `wq '.

por exemplo, aqui está o código do meu arquivo Sweave:

<<label=fig5plot, echo=F, results=hide>>=
plot5<-grid.arrange(plot4, arrangeGrob(plot1, plot2, plot3, ncol=1), 
                    ncol=2, widths=c(1,1.2))
@
\begin{figure}[]
    \begin{center}
<<label=fig5,fig=TRUE,echo=T, width=10,height=12>>=
<<fig5plot>>
@
\end{center}
\caption{Combined plots using the `arrangeGrob' command.}
\label{fig:five}
\end{figure}

que produz a seguinte saída: insira a descrição da imagem aqui

BTW, alguém me diga por que o '> NA' aparece?

user441706
fonte
Talvez seja necessário configurar as janelas de visualização você mesmo - grid.arrangepode não ser flexível o suficiente (pesquisar stackoverflow para "[r] janela de visualização em grade")
Ben Bolker
2
@BenBolker apontou você em uma direção proveitosa usando grid. Veja também o livro ggplot2 de Hadley, Seção 8.4.2.
Ari B. Friedman
1
@BenBolker grid.arrangepode ser usado com viewports aninhadas usando seu companheiro arrangeGrob(essencialmente retornando a gTree), como no exemplo que dei abaixo.
baptiste de
1
sua atribuição final para plot5não é necessária, pois grid.arrangenão retorna nada (NULL). Se você quiser salvar o grob resultante, use arrangeGrobnovamente (e grid.drawpara exibi-lo).
baptiste de

Respostas:

73

grid.arrangedesenha diretamente no dispositivo; se você quiser combiná-lo com outros objetos de grade que você precisa arrangeGrob, como em

 p = rectGrob()
 grid.arrange(p, arrangeGrob(p,p,p, heights=c(3/4, 1/4, 1/4), ncol=1),
              ncol=2)

Editar (07/2015): com v> 2.0.0 você pode usar o layout_matrixargumento,

 grid.arrange(p,p,p,p, layout_matrix = cbind(c(1,1,1), c(2,3,4)))
batista
fonte
6
Você poderia explicar como a cbind(c(1,1,1), c(2,3,4))matriz descreve a disposição das figuras?
Ron Gejman
5
@RonGejman é fácil se você imprimir a matriz 3x2 na tela: a primeira coluna é toda 1s, é onde fica o primeiro gráfico, abrangendo as três linhas; a segunda coluna contém os gráficos 2, 3, 4, cada um ocupando uma linha.
baptiste
17

Tentei descobrir com a grade e pensei que tinha feito, mas acabei falhando (embora olhando agora para o código na função que cito abaixo, posso ver que estava muito perto ... :-)

O pacote 'wq' tem uma layOutfunção que fará isso por você:

p1 <- qplot(mpg, wt, data=mtcars)
layOut(list(p1, 1:3, 1),   # takes three rows and the first column
        list(p1, 1, 2),    # next three are on separate rows
         list(p1, 2,2), 
          list(p1, 3,2))

insira a descrição da imagem aqui

IRTFM
fonte
Uau, essa é uma função útil! Acho que copiar + colar pode ter falhado; você quis dizer para g1, g2, etc ser todos p1?
joran
3
@joran: Sim. Não consigo lembrar qual das "três virtudes da programação" é Preguiça, mas sei que existe em algum lugar.
IRTFM
Obrigado! Funcionou muito bem. Veja acima.
user441706
2

Outra alternativa é a patchworkembalagem de Thomas Lin Pedersen.

# install.packages("devtools")
# devtools::install_github("thomasp85/patchwork")
library(patchwork)

Gere alguns gráficos.

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + facet_grid(rows = vars(gear))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
p3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
p4 <- ggplot(mtcars) + geom_bar(aes(carb))

Agora organize as parcelas.

p1 + (p2 / p3 / p4)

insira a descrição da imagem aqui

Markus
fonte
1

Há também um pacote com várias figuras que vale a pena mencionar. Veja também esta resposta .

library(ggplot2)
theme_set(theme_bw())

q1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
q2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
q3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
q4 <- ggplot(mtcars) + geom_bar(aes(carb))

library(magrittr)
library(multipanelfigure)

figure1 <- multi_panel_figure(columns = 2, rows = 3, panel_label_type = "upper-roman")

figure1 %<>%
  fill_panel(q1, column = 1, row = 1:3) %<>%
  fill_panel(q2, column = 2, row = 1) %<>%
  fill_panel(q3, column = 2, row = 2) %<>%
  fill_panel(q4, column = 2, row = 3)
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
figure1

Criado em 16/07/2018 pelo pacote reprex (v0.2.0.9000).

Tung
fonte