Как мне организовать список переменных графиков с помощью 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.

Я хочу оформить участки используя grid.arrange()в gridExtra.

Как я могу это сделать, если количество графиков plistварьируется?

Это работает: grid.arrange(plist[[1]],plist[[2]],plist[[3]],plist[[4]],plist[[5]])

но мне нужно более общее решение. мысли?

Майасаура
источник

Ответы:

139

Как насчет этого:

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

введите описание изображения здесь

Джош О'Брайен
источник
Это хорошо, за исключением того, что функция не может обрабатывать NULL-объекты.
Roman Luštrik
Джош. Я люблю тебя. До сих пор потратил на это 2 часа. Не могли бы вы объяснить, почему это не работает? grid.arrange(plist[[1:length(plist)]], ncol = nCol))Я получаю такую ​​ошибку: Error in hl.plots[[1:12]] : no such index at level 3Спасибо!
Anto
2
@Anto Там , кажется, несколько вещей неправильно с этим кодом, но один дает вам отображаемую ошибку, вероятно , вызвано таким же ошибка , как показано здесь: x <- list(1,2); x[[3:1]]. В более широком смысле, используйте что-то вроде, plist[...]а не plist[[...]]для подмножества. И затем используйте do.call(), который мы должны использовать, потому что grid.arrange()он не настроен на использование списка в качестве первого аргумента. Ура и удачи!
Джош О'Брайен,
31

Вы можете использовать grid.arrange()и arrangeGrob()со списками, если вы указываете список с помощью grobs =аргумента в каждой функции. Например, в приведенном вами примере:

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
Майкл Олрогге
источник
1
Мне потребовалось слишком много времени, чтобы найти этот ответ ... спасибо! Это самое простое.
Мэтт Л.
16

Для полноты (и поскольку этот старый вопрос, на который уже был дан ответ , недавно был возрожден ), я хотел бы добавить решение с использованием cowplotпакета:

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

введите описание изображения здесь

Уве
источник
любая идея, почему передача списка графиков с использованием этого кода возвращает эту ошибку: Error in ggplot_to_gtable(x) : Argument needs to be of class "ggplot" or "gtable"
geog_newbie
Как были созданы сюжеты? Используете ggplot2пакетную или базовую графику?
Уве
ggplot2. grid.arrangeу меня почти сработало - но, оказывается, мой список участков не заполняется. Я разместил проблему как вопрос: stackoverflow.com/questions/43216262/… . Итак, мне интересно, могло ли это быть проблемой и для коровьего заговора
geog_newbie
10

Я знаю, что в вопросе конкретно говорится об использовании пакета gridExtra , но wrap_plotsфункция из пакета patchwork - отличный способ обрабатывать список переменной длины:

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)

введите описание изображения здесь

Полезно то, что вам не нужно указывать, сколько столбцов требуется, и вы будете стремиться к тому, чтобы количество столбцов и строк оставалось равным. Например:

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

Узнайте больше о пакете пэчворк здесь

Майкл Харпер
источник
Кажется, я не могу установить пакет, который вы здесь упомянули
baxx
Вы пробовали запустить строку установки, которая закомментирована выше devtools::install_github("thomasp85/patchwork")?
Майкл Харпер
Спасибо, нет. Я просто пытался использовать установку из RStudio.
baxx
1
Пакет пока недоступен на CRAN, поэтому вам нужно установить его через GitHub. Надеюсь, так долго не будет, поскольку это отличный пакет!
Майкл Харпер
1

Чтобы уместить все графики на одной странице, вы можете рассчитать количество столбцов и строк следующим образом:

x = length(plots)

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

Поскольку большинство функций построения графиков имеют аргументы ncol и nrow, вы можете просто вставить их туда. Мне нравится ggarrange от ggpubr.

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

Так будет больше строк, чем столбцов, поэтому поменяйте местами, если хотите наоборот. Т.е. для 6 графиков это даст 3 строки и 2 столбца, а не наоборот.

Адам Уоринг
источник