Salvando a plotagem grid.arrange () no arquivo

137

Estou tentando plotar várias parcelas usando ggplot2, organizando-as usando grid.arrange(). Desde que consegui encontrar alguém descrevendo o problema exato que tenho, citei a descrição do problema no link :

Quando eu uso ggsave()depois grid.arrange(), ou seja,

grid.arrange(sgcir1,sgcir2,sgcir3,ncol=2,nrow=2)
ggsave("sgcirNIR.jpg")

Eu não salvo o gráfico da grade, mas o último gráfico gg individual. Existe alguma maneira de realmente salvar o gráfico como exibido grid.arrange()usando ggsave()algo semelhante? Além de usar a maneira mais antiga

jpeg("sgcirNIR.jpg")
grid.arrange(sgcir1,sgcir2,sgcir3,ncol=2,nrow=2)
dev.off()

O mesmo link fornece a solução abaixo:

require(grid)
require(gridExtra)
p <- arrangeGrob(qplot(1,1), textGrob("test"))
grid.draw(p) # interactive device
ggsave("saving.pdf", p) # need to specify what to save explicitly

No entanto, não consigo descobrir como usar ggsave()para salvar a saída da grid.arrange()chamada no código a seguir, retirado do link :

library(ggplot2)
library(gridExtra)
dsamp <- diamonds[sample(nrow(diamonds), 1000), ] 

p1 <- qplot(carat, price, data=dsamp, colour=clarity)
p2 <- qplot(carat, price, data=dsamp, colour=clarity, geom="path")

g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)}

legend <- g_legend(p1)
lwidth <- sum(legend$width)

## using grid.arrange for convenience
## could also manually push viewports
grid.arrange(arrangeGrob(p1 + theme(legend.position="none"),
                                        p2 + theme(legend.position="none"),
                                        main ="this is a title",
                                        left = "This is my global Y-axis title"), legend, 
                     widths=unit.c(unit(1, "npc") - lwidth, lwidth), nrow=1)

# What code to put here to save output of grid.arrange()?
Eu gosto de codificar
fonte
6
Usepng(); grid.arrange(); ggplot(); ggplot(); dev.off()
Andrie
2
Não print(ggplot())?
IRTFM 12/06
@ DWin Sim, provavelmente! :-)
Andrie
1
@ Andrie O que você sugere funciona, mas a resolução da imagem é muito baixa. Quando guardo uma única ggplotutilização ggsave(), a resolução da imagem é muito maior. Existe uma maneira de salvar a saída grid.arrange()com alta resolução, como seria se fosse uma única plotagem salva ggsave()? Se eu fornecer, por exemplo, as opções, png(...,height=1600, width=2500)a imagem parece muito desfocada.
Eu gosto de codificar

Respostas:

142

grid.arrangedesenha diretamente em um dispositivo. arrangeGrob, por outro lado, não desenha nada, mas retorna um grob g, para o qual você pode passar ggsave(file="whatever.pdf", g).

O motivo pelo qual ele funciona de maneira diferente do que com os objetos ggplot, onde por padrão o último gráfico está sendo salvo, se não especificado, é que o ggplot2 invisivelmente acompanha o gráfico mais recente, e acho que não grid.arrangedeve mexer com esse contador particular do pacote.

baptiste
fonte
3
Quando tento isso, recebo um erro dizendo que g não é do tipo certo?
Jack Aidley
O @JackAidley faz uma nova pergunta, com um exemplo reprodutível mínimo e sua sessionInfo () (verifique se você tem versões recentes do R e pacotes).
baptiste
3
@DaveX, por favor, não divulgue essas informações enganosas; nãoplot(g) é o caminho certo para exibir uma tabela, use em seu lugar. grid.draw(g)
baptiste
@baptiste Obrigado e reformulado: Observe que, se você tentar ver o resultado g <-arrangeGrob(...)com, print(g)obterá uma tabela de texto listando os objetos gráficos em vez do gráfico. Tente grid.draw(g)renderizar o gráfico como gráfico. -
Dave X
7
O ggsave não está mais trabalhando com (alguns ou todos) grobs.
vak
47

Eu tive alguns problemas com a proposta de babptiste, mas finalmente entendi. Aqui está o que você deve usar:

 # draw your plots
 plot1 <- ggplot(...) # this specifies your first plot
 plot2 <- ggplot(...) # this specifies your second plot
 plot3 <- ggplot(...) # this specifies your third plot

 #merge all three plots within one grid (and visualize this)
 grid.arrange(plot1, plot2, plot3, nrow=3) #arranges plots within grid

 #save
 g <- arrangeGrob(plot1, plot2, plot3, nrow=3) #generates g
 ggsave(file="whatever.pdf", g) #saves g

Isso deve funcionar bem.

user2B4L2
fonte
24

Outra maneira fácil de salvar um grid.arrange em um arquivo pdf é usar pdf ():

pdf("filename.pdf", width = 8, height = 12) # Open a new pdf file
grid.arrange(plot1, plot2, plot3, nrow=3) # Write the grid.arrange in the file
dev.off() # Close the file

Permite mesclar outras coisas além de ggplots no arranjo, como tabelas ...

JohnBee
fonte
7

Eu pensei que valia a pena adicionar a isso. Eu tive problemas com o acima, com o ggsave produzindo um erro: "plot deveria ser um plot ggplot2"

Graças a esta resposta: Salvar um gráfico com o ggsave depois de usar o ggplot_build e o ggplot_gtable Eu tenho uma alteração no código acima.

  # draw your plots
 plot1 <- ggplot(...) # this specifies your first plot
 plot2 <- ggplot(...) # this specifies your second plot
 plot3 <- ggplot(...) # this specifies your third plot

 #merge all three plots within one grid (and visualize this)
 grid.arrange(plot1, plot2, plot3, nrow=3) #arranges plots within grid

 #save
 ggsave <- ggplot2::ggsave; body(ggsave) <- body(ggplot2::ggsave)[-2]

A linha acima necessária para corrigir o erro

 g <- arrangeGrob(plot1, plot2, plot3, nrow=3) #generates g
 ggsave(file="whatever.pdf", g) #saves g

Agora funciona bem para mim.

docjg
fonte
Eu precisava disso. Aparentemente, a versão de desenvolvimento do ggplot2 remove a falha de teste de classe assim, mas a versão do CRAN atualmente (21-10-2015) não.
Dave X
2
Isso funciona com o marrangeGrob para mim, mas não com o organizeGrob ou grid.arrange. Obrigado!
k13 23/10/2015
3

Você não precisa usar o organizeGrob, pode atribuir o resultado de grid.arrange diretamente a um gráfico e salvá-lo usando ggsave:

p3 <- grid.arrange(p1,p2, nrow = 1)
ggsave("filename.jpg", p3)
RegressionSquirrel
fonte
2

Outra solução simples: logo após o seu grid.arrange()

grid.arrange(plot1, plot2, plot3, nrow=3)

você faz um dev.copy()

dev.copy(pdf,"whatever.pdf")
dev.off()
TeYaP
fonte