Zapisywanie wykresu grid.arrange () do pliku

137

Próbuję wykreślić wiele działek za pomocą ggplot2, układając je za pomocą grid.arrange(). Ponieważ udało mi się znaleźć kogoś, kto dokładnie opisałby mój problem, zacytowałem z opisu problemu z linku :

Kiedy używam ggsave()po grid.arrange()tj

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

Nie zapisuję wykresu siatki, ale ostatni indywidualny ggplot. Czy istnieje sposób na zapisanie wyświetlanego wykresu za grid.arrange()pomocą ggsave()lub czegoś podobnego? Inaczej niż starszym sposobem

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

Ten sam link daje poniższe rozwiązanie:

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

Jednak nie mogę dowiedzieć się, jak użyć ggsave()do zapisania danych wyjściowych grid.arrange()wywołania w poniższym kodzie, który jest pobierany z linku :

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()?
Lubię kodować
źródło
6
Użyjpng(); grid.arrange(); ggplot(); ggplot(); dev.off()
Andrie,
2
Nie print(ggplot())?
IRTFM
@DWin Tak, prawdopodobnie! :-)
Andrie
1
@Andrie To, co sugerujesz, działa, ale rozdzielczość obrazu jest bardzo niska. Kiedy zapisuję pojedyncze ggplotużycie ggsave(), rozdzielczość obrazu jest znacznie wyższa. Czy istnieje sposób na zapisanie wyjścia grid.arrange()z wysoką rozdzielczością, tak jakby to był zapisany pojedynczy wykres ggsave()? Jeśli podam na przykład opcje, png(...,height=1600, width=2500)obraz wygląda na bardzo rozmyty.
Lubię

Odpowiedzi:

142

grid.arrangerysuje bezpośrednio na urządzeniu. arrangeGrobz drugiej strony niczego nie rysuje, ale zwraca grob g, do którego możesz przejść ggsave(file="whatever.pdf", g).

Powodem, dla którego działa inaczej niż w przypadku obiektów ggplot, w których domyślnie zapisywany jest ostatni wykres, jeśli nie jest określony, jest to, że ggplot2 niewidocznie śledzi najnowszy wykres i nie sądzę, że grid.arrangepowinien zadzierać z tym licznikiem prywatnym dla pakietu.

baptiste
źródło
3
Kiedy próbuję tego, pojawia się błąd z informacją, że g nie jest odpowiedniego typu?
Jack Aidley
@JackAidley zadaj nowe pytanie, z minimalnym samodzielnym odtwarzalnym przykładem i swoją sessionInfo () (upewnij się, że masz najnowsze wersje R i pakietów).
baptiste
3
@DaveX, proszę, nie rozpowszechniaj tych mylących informacji; nieplot(g) jest właściwym sposobem wyświetlania gtable, użyj zamiast tego. grid.draw(g)
baptiste
@baptiste Dzięki i przerobiono: Zauważ, że jeśli spróbujesz zobaczyć wynik g <-arrangeGrob(...)z print(g), otrzymasz tabelę tekstową zawierającą obiekty graficzne, a nie grafikę. Spróbuj grid.draw(g)renderować grafikę jako grafikę. -
Dave X
7
ggsave nie działa już z (niektórymi lub wszystkimi) grobami.
vak
47

Miałem problemy z propozycją babptiste, ale w końcu udało mi się. Oto, czego powinieneś użyć:

 # 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

To powinno działać dobrze.

user2B4L2
źródło
24

Innym prostym sposobem zapisania grid.arrange do pliku pdf jest użycie 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

Pozwala łączyć w aranżację inne rzeczy niż ggplots, np. Tabele ...

JohnBee
źródło
7

Pomyślałem, że warto do tego dodać. Miałem problemy z powyższym, ggsave generował błąd: "wykres powinien być wykresem ggplot2"

Dzięki tej odpowiedzi: Zapisując wykres z ggsave po użyciu ggplot_build i ggplot_gtable mam poprawkę do powyższego kodu.

  # 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]

Powyższa linia wymagała naprawy błędu

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

Teraz działa na mnie dobrze.

docjg
źródło
Potrzebowałem tego. Wygląda na to, że wersja rozwojowa ggplot2 usuwa błąd testu klasy w ten sposób, ale obecnie wersja CRAN (2015-10-21) nie.
Dave X
2
To działa z marrangeGrob dla mnie, ale nie zrangeGrob lub grid.arrange. @ DaveX, czy musiałeś zrobić coś innego, aby działał, poza modyfikacją ggsave, jak pokazano powyżej? Dzięki!
k13
3

Nie ma potrzeby korzystania z programurangeGrob, można przypisać wynik działania grid.arrange bezpośrednio do wykresu i zapisać go za pomocą ggsave:

p3 <- grid.arrange(p1,p2, nrow = 1)
ggsave("filename.jpg", p3)
RegressionSquirrel
źródło
2

Kolejne proste rozwiązanie: zaraz po Twoim grid.arrange()

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

robisz dev.copy()

dev.copy(pdf,"whatever.pdf")
dev.off()
TeYaP
źródło