Как я могу получить "несбалансированную" сетку ggplots?

94

С помощью grid.arrangeя могу расположить несколько ggplotфигур в сетке, чтобы получить фигуру из нескольких панелей, используя что-то вроде:

library(ggplot2)
library(grid)
library(gridExtra)

сгенерируйте несколько графиков ggplot2, затем

plot5 <- grid.arrange(plot4, plot1, heights=c(3/4, 1/4), ncol=1, nrow=2)

Как я могу получить «несбалансированный» макет с двумя столбцами с одним графиком во всем первом столбце и тремя графиками во втором столбце? Я играл с подходом «сетка сеток», пытаясь использовать grid.arrangeдля построения одной сетки (например plot5, выше) против другого графика, но получил:

Ошибка в аранжировкеGrob (..., as.table = as.table, clip = clip, main = main,: input must be grobs!

Обновить:

Спасибо за совет. Я изучу viewportsи grid. Тем временем, благодаря @DWin, layOutфункция в пакете wq очень хорошо работала для фигуры компиляции в моем Sweaveдокументе: введите описание изображения здесь

Обновление 2:

Команда arrangeGrob(предложенная @baptiste) также хорошо работает и кажется очень интуитивно понятной - по крайней мере, было легко изменить ширину двух столбцов. Он также имеет то преимущество, что не требует пакета `wq '.

например, вот код из моего файла Sweave:

<<label=fig5plot, echo=F, results=hide>>=
plot5<-grid.arrange(plot4, arrangeGrob(plot1, plot2, plot3, ncol=1), 
                    ncol=2, widths=c(1,1.2))
@
\begin{figure}[]
    \begin{center}
<<label=fig5,fig=TRUE,echo=T, width=10,height=12>>=
<<fig5plot>>
@
\end{center}
\caption{Combined plots using the `arrangeGrob' command.}
\label{fig:five}
\end{figure}

который дает следующий результат: введите описание изображения здесь

Кстати, кто-нибудь скажет мне, почему появляется '> NA'?

user441706
источник
Возможно, вам придется настроить окна просмотра самостоятельно - grid.arrangeвозможно, это окажется недостаточно гибким (поисковый стек для "[r] grid viewport")
Бен Болкер
2
@BenBolker указал вам на плодотворное направление использования grid. См. Также книгу Хэдли ggplot2, раздел 8.4.2.
Ари Б. Фридман
1
@BenBolker grid.arrangeможно использовать с вложенными окнами просмотра, используя его сопутствующий arrangeGrobобъект (по существу возвращающий a gTree), как в примере, который я привел ниже.
baptiste
1
ваше окончательное присвоение plot5не требуется, так как grid.arrangeничего не возвращает (NULL). Если вы хотите сохранить получившийся grob, используйте его arrangeGrobснова (и grid.drawотобразите его).
baptiste

Ответы:

73

grid.arrangeрисует прямо на устройстве; если вы хотите объединить его с другими объектами сетки, которые вам нужны arrangeGrob, как в

 p = rectGrob()
 grid.arrange(p, arrangeGrob(p,p,p, heights=c(3/4, 1/4, 1/4), ncol=1),
              ncol=2)

Изменить (07/2015): с v> 2.0.0 вы можете использовать layout_matrixаргумент,

 grid.arrange(p,p,p,p, layout_matrix = cbind(c(1,1,1), c(2,3,4)))
батист
источник
6
Не могли бы вы объяснить, как cbind(c(1,1,1), c(2,3,4))матрица описывает расположение фигур?
Рон Гейман,
5
@RonGejman - это просто, если вы напечатаете матрицу 3x2 на экране: первый столбец - это все единицы, это то место, где находится первый график, охватывающий три строки; второй столбец содержит графики 2, 3, 4, каждый из которых занимает одну строку.
Батист
17

Я попытался выяснить это с помощью сетки и подумал, что у меня это получилось, но в конечном итоге это не удалось (хотя теперь, глядя на код в функции, которую я цитирую ниже, я вижу, что я был действительно близок ... :-)

В пакете wq есть layOutфункция, которая сделает это за вас:

p1 <- qplot(mpg, wt, data=mtcars)
layOut(list(p1, 1:3, 1),   # takes three rows and the first column
        list(p1, 1, 2),    # next three are on separate rows
         list(p1, 2,2), 
          list(p1, 3,2))

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

IRTFM
источник
Вау, это полезная функция! Я думаю, что копирование + вставка, возможно, вас подвело; Вы имели в виду g1, g2и т. д., чтобы все было p1?
joran
3
@joran: Я сделал. Я не могу вспомнить, какое из «трех достоинств программирования» - это лень, но я знаю, что она где-то есть.
IRTFM
Спасибо! Сработало очень красиво. См. Выше.
user441706
2

Другой альтернативой является patchworkпакет Томаса Лина Педерсена.

# install.packages("devtools")
# devtools::install_github("thomasp85/patchwork")
library(patchwork)

Создайте несколько сюжетов.

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + facet_grid(rows = vars(gear))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
p3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
p4 <- ggplot(mtcars) + geom_bar(aes(carb))

А теперь оформляйте участки.

p1 + (p2 / p3 / p4)

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

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

Также стоит упомянуть пакет multipanelfigure . См. Также этот ответ .

library(ggplot2)
theme_set(theme_bw())

q1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
q2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
q3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
q4 <- ggplot(mtcars) + geom_bar(aes(carb))

library(magrittr)
library(multipanelfigure)

figure1 <- multi_panel_figure(columns = 2, rows = 3, panel_label_type = "upper-roman")

figure1 %<>%
  fill_panel(q1, column = 1, row = 1:3) %<>%
  fill_panel(q2, column = 2, row = 1) %<>%
  fill_panel(q3, column = 2, row = 2) %<>%
  fill_panel(q4, column = 2, row = 3)
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
figure1

Создано 16.07.2018 пакетом REPEX (v0.2.0.9000).

Тунг
источник