Jak ustawić zmienną listę działek za pomocą grid.arrange?

92
library(ggplot2)
df <- data.frame(x=1:10, y=rnorm(10))
p1 <- ggplot(df, aes(x,y)) + geom_point()
plist <- list(p1,p1,p1,p1,p1)
# In my real example,a plot function will fit a ggplot to a list of datasets 
#and return a list of ggplots like the example above.

Chciałbym ułożyć działki używając grid.arrange()w gridExtra.

Jak mam to zrobić, jeśli liczba działek plistjest zmienna?

To działa: grid.arrange(plist[[1]],plist[[2]],plist[[3]],plist[[4]],plist[[5]])

ale potrzebuję bardziej ogólnego rozwiązania. myśli?

Maiasaura
źródło

Odpowiedzi:

139

Co powiesz na to:

library(gridExtra)
n <- length(plist)
nCol <- floor(sqrt(n))
do.call("grid.arrange", c(plist, ncol=nCol))

wprowadź opis obrazu tutaj

Josh O'Brien
źródło
To fajne, z wyjątkiem tego, że funkcja nie obsługuje obiektów NULL.
Roman Luštrik
Josh. Kocham Cię. Do tej pory spędziłem nad tym 2 godziny. Czy mógłbyś wyjaśnić, dlaczego to nie działa: grid.arrange(plist[[1:length(plist)]], ncol = nCol))Otrzymuję taki błąd: Error in hl.plots[[1:12]] : no such index at level 3Dzięki!
Anto
2
@Anto Wydaje się, że kilka rzeczy złego kodu, ale ten daje wyświetlany błąd jest prawdopodobnie spowodowane przez ten sam rodzaj błędu, jak pokazano tutaj: x <- list(1,2); x[[3:1]]. Szerzej, użyj plist[...]raczej czegoś podobnego niż plist[[...]]wykonywania podzbiorów. A następnie użyj do.call(), którego musimy użyć, ponieważ grid.arrange()nie jest skonfigurowany do przyjmowania listy jako pierwszego argumentu. Pozdrawiam i powodzenia!
Josh O'Brien
31

Możesz używać grid.arrange()iz arrangeGrob()listami, o ile określisz listę przy użyciu grobs =argumentu w każdej funkcji. Np. W podanym przykładzie:

library(ggplot2)
library(gridExtra)
df <- data.frame(x=1:10, y=rnorm(10))
p1 <- ggplot(df, aes(x,y)) + geom_point()
plist <- list(p1,p1,p1,p1,p1)

grid.arrange(grobs = plist, ncol = 2) ## display plot
ggsave(file = OutFileName, arrangeGrob(grobs = plist, ncol = 2))  ## save plot
Michael Ohlrogge
źródło
1
Zbyt długo zajęło mi znalezienie tej odpowiedzi ... dzięki! To jest najprostsze.
Matt L.
16

Ze względu na kompletność (a ponieważ to stare pytanie, na które już udzielono odpowiedzi , zostało ostatnio przywrócone ) chciałbym dodać rozwiązanie wykorzystujące cowplotpakiet:

cowplot::plot_grid(plotlist = plist, ncol = 2)

wprowadź opis obrazu tutaj

Uwe
źródło
każdy pomysł, dlaczego przekazanie listy działek przy użyciu tego kodu zwraca ten błąd: Error in ggplot_to_gtable(x) : Argument needs to be of class "ggplot" or "gtable"
geog_newbie
Jak powstały działki? Korzystasz z ggplot2pakietu lub grafiki bazowej?
Uwe
ggplot2. grid.arrangeprawie zadziałało dla mnie - ale okazuje się, że moja lista działek się nie zapełnia. Opublikowałem ten problem jako pytanie: stackoverflow.com/questions/43216262/… . Zastanawiam się więc, czy to mógł być problem również dla cowplot
geog_newbie
10

Wiem, że pytanie konkretnie określa użycie pakietu gridExtra , ale wrap_plotsfunkcja z pakietu patchwork to świetny sposób na obsługę listy o zmiennej długości:

library(ggplot2)
# devtools::install_github("thomasp85/patchwork")
library(patchwork)

df <- data.frame(x=1:10, y=rnorm(10))
p1 <- ggplot(df, aes(x,y)) + geom_point()
plist <- list(p1,p1,p1,p1,p1)

wrap_plots(plist)

wprowadź opis obrazu tutaj

Przydatną rzeczą jest to, że nie musisz określać, ile kolumn jest wymaganych, i będziesz dążyć do utrzymania równej liczby kolumn i wierszy. Na przykład:

plist <- list(p1,p1,p1,p1,p1,p1,p1,p1,p1,p1,p1,p1,p1)
wrap_plots(plist) # produces a 4 col x 4 row plot

Dowiedz się więcej o pakiecie patchwork tutaj

Michael Harper
źródło
Nie mogę zainstalować pakietu, o którym tutaj wspomniałeś
baxx
Czy próbowałeś uruchomić linię instalacyjną, która jest zakomentowana powyżej devtools::install_github("thomasp85/patchwork")?
Michael Harper
Dziękuję, nie zrobiłem. Właśnie próbowałem użyć instalacji z RStudio.
baxx
1
Pakiet nie jest jeszcze dostępny w CRAN, więc musisz go zainstalować przez GitHub. Miejmy nadzieję, że nie potrwa to długo, ponieważ jest to doskonały pakiet!
Michael Harper
1

Aby zmieścić wszystkie wykresy na jednej stronie, możesz obliczyć liczbę kolumn i wierszy w następujący sposób:

x = length(plots)

cols = round(sqrt(x),0)
rows = ceiling(x/cols)

Ponieważ większość funkcji kreślących ma ncol i nrow jako argumenty, możesz je tam po prostu wstawić. Lubię ggarrange z ggpubr.

ggarrange(plotlist = plots, ncol=cols, nrow = rows)

To faworyzuje więcej wierszy niż kolumn, więc odwróć, jeśli chcesz odwrotnie. To znaczy dla 6 poletek da to 3 rzędy i 2 kolumny, a nie na odwrót.

Adam Waring
źródło