2012-07-30 30 views
24

Byłbym wdzięczny za pomoc w następującym problemie. Znam kilka sposobów na zapisanie pojedynczego wykresu w pliku. Moje pytanie brzmi: Jak poprawnie zapisać plik multiplot?R - zapisz multiplot do pliku

Na początku nie jestem doświadczonym użytkownikiem R. Używam ggplot2 do tworzenia moich działek, a inną rzeczą, o której powinienem wspomnieć, jest to, że używam GUI RStudio. Korzystając z example z książki kucharskiej R, mogę utworzyć wiele wątków w jednym oknie.

Chciałbym zapisać ten tak zwany multiplot do pliku (najlepiej jako jpeg), ale jakoś nie udało się tego zrobić.

Tworzę ten multiplot następująco:

##define multiplot function 
    multiplot <- function(..., plotlist=NULL, cols) { 
     require(grid) 

     # Make a list from the ... arguments and plotlist 
     plots <- c(list(...), plotlist) 

     numPlots = length(plots) 

     # Make the panel 
     plotCols = cols       # Number of columns of plots 
     plotRows = ceiling(numPlots/plotCols) # Number of rows needed, calculated from # of cols 

     # Set up the page 
     grid.newpage() 
     pushViewport(viewport(layout = grid.layout(plotRows, plotCols))) 
     vplayout <- function(x, y) 
      viewport(layout.pos.row = x, layout.pos.col = y) 

     # Make each plot, in the correct location 
     for (i in 1:numPlots) { 
      curRow = ceiling(i/plotCols) 
      curCol = (i-1) %% plotCols + 1 
      print(plots[[i]], vp = vplayout(curRow, curCol)) 
     } 

    } 

## define subplots (short example here, I specified some more aesthetics in my script) 
plot1a <- qplot(variable1,variable2,data=Mydataframe1) 
plot1b <- qplot(variable1,variable3,data=Mydataframe1) 
plot1c <- qplot(variable1,variable2,data=Mydataframe2) 
plot1d <- qplot(variable1,variable3,data=Mydataframe2) 

## plot in one frame 
Myplot <- multiplot(plot1a,plot1b,plot1c,plot1d, cols=2) 

To daje pożądanego rezultatu. Problem pojawia się, gdy próbuję zapisać do pliku. Mogę to zrobić ręcznie w RStudio (używając Export -> Save plot as image), ale chciałbym uruchomić wszystko w skrypcie. Udaje mi się tylko zapisać subplot1d (który jest last_plot()), a nie cały multiplot.

Co próbowałem dotąd:

  1. Korzystanie ggsave

    ggsave(filename = "D:/R/plots/Myplots.jpg") 
    

    Skutkuje to tylko subplot 1d zapisywane.

  2. Korzystanie JPEG(), print() i() dev.off

    jpeg(filename = "Myplot.jpg", pointsize =12, quality = 200, bg = "white", res = NA, restoreConsole = TRUE) 
    print(Myplot) 
    dev.off() 
    

    Wynika to w zupełnie biały obraz (tylko tłem zakładam). print (Myplot) zwraca NULL.

Nie jestem pewien, co robię źle tutaj. Mój brak zrozumienia R jest powodem, dla którego utknąłem, próbując znaleźć rozwiązanie. Czy ktoś może wyjaśnić, co robię źle, a może zaproponować sposób rozwiązania mojego problemu (problemów)?

+4

Możesz także użyć ** gridExtra :: grid.aranżacja (działka1a, wykres1b, wykres1c, wykres1d, ncol = 2) ** – dickoa

+0

Pakiet gridExtra nie zawiera grid.arrange, zawiera structGrob, który wydaje się zapewniać taką samą funkcjonalność. Wydaje mi się też, że pamiętam funkcję o nazwie grid.arrange, może autor zmienił tytuły funkcji w pakiecie. –

+0

'grid.arrange' powinno znajdować się w gridExtra. Nawiasem mówiąc, jedną z zalet 'arrangeGrob' vs' multiplot' jest to, że jest kompatybilny z 'ggsave', i że możesz przechowywać kompozytowy grob do późniejszego użycia. – baptiste

Odpowiedz

18

To dlatego, że Myplot jest zwracaną wartością z funkcji multiplot i nie zwraca nic (jej zadaniem jest wydrukowanie wykresów). Musisz wywołać multiplot z otwartym urządzeniem jpeg:

jpeg(filename = "Myplot.jpg", pointsize =12, quality = 200, bg = "white", res = NA, restoreConsole = TRUE) 
multiplot(plot1a,plot1b,plot1c,plot1d, cols=2) 
dev.off() 

powinien działać.

+0

To naprawdę takie proste! Wielkie dzięki za wyjaśnienie, dlaczego moje podejście nie zadziałało. –

17

Używanie example code (R książki kucharskiej), to działa na mnie

png("chickweight.png") 
multiplot(p1, p2, p3, p4, cols=2) 
dev.off() 

enter image description here

+1

Masz rację, ale twój kod jest nieco inny niż @M_Vermeulen, najpierw kreśli 4 wątki, oczekując, że 'multiplot' zwróci obiekt siatki. Może to, że 'grid.arrange' pokazuje to zachowanie? –

+0

@PaulHiemstra: Nie sądzę, żebym wybrał inne podejście, spójrz na przykładową stronę. Prawdziwy problem wyjaśnił bardzo dobrze @Spacedman. I tak 'grid.arrange' pokazuje to samo zachowanie – dickoa

+0

Twój kod zawiera już poprawkę @Spacedman, multiplot musi znajdować się wewnątrz połączenia' png'. –

6

I przez wzgląd na kompletność, ggsave nie działa, jak to tylko oszczędza ostatni obiekt ggplot drukowaną, która w swojej sprawa to tylko ostatni spisek. Jest to spowodowane faktem, że multiplot tworzy wykres przez rysowanie obiektów ggplot na różnych podzbiorach całego urządzenia graficznego. Alternatywą jest utworzenie wykresu poprzez połączenie obiektów ggplot w jeden duży obiekt ggplot, a następnie wydrukowanie obiektu. Byłoby to zgodne z ggsave. To podejście jest realizowane przez pakiet arrangeGrob w pakiecie gridExtra.

+2

technicznie, 'arrangeGrob' nie tworzy" jednego dużego obiektu ggplot ", zwraca gTree klasy" aranżuj ", a jeśli są ggplots na liście dzieci, to klasa również dziedziczy po" ggplot ", aby oszukać ggsave . – baptiste

+0

Dzięki za bardziej szczegółowe informacje. –