Подтвердить что ты не робот

Выровнять участки в ggplot

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

Я попытался использовать различные параметры темы в ggplot2, чтобы изменить размер графика и переместить метку оси y, но никто не работал, чтобы выровнять графики. Я хочу, чтобы графики располагались в квадрате 2 x 2, чтобы каждый график имел одинаковый размер и выравнивание по оси x.

Вот несколько тестовых данных:

A <- c(1,5,6,7,9)
B <- c(10,56,64,86,98)
C <- c(2001,3333,5678,4345,5345)
D <- c(13446,20336,24333,34345,42345)
L <- c(20,34,45,55,67)
M <- data.frame(L, A, B, C, D)

И код, который я использую для построения:

x1 <- ggplot(M, aes(L, A,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x2 <- ggplot(M, aes(L, B,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x3 <- ggplot(M, aes(L, C,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x4 <- ggplot(M, aes(L, D,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
grid.arrange(x1,x2,x3,x4,nrow=2)

Если вы запустите этот код, вы увидите, что нижние два графика имеют меньшую площадь заговора из-за большей длины единиц осей y.

Как сделать окна реального графика одинаковыми?

4b9b3361

Ответ 1

Я бы использовал огранку для этой проблемы:

library(reshape2)
dat <- melt(M,"L") # When in doubt, melt!

ggplot(dat, aes(L,value)) + 
geom_point() + 
stat_smooth(method="lm") + 
facet_wrap(~variable,ncol=2,scales="free")

Example

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

Ответ 2

Edit

Более простые решения: 1) использовать пакет cowplot (см. ответ здесь); или 2) используйте пакет egg, доступный на github.

# devtools::install_github("baptiste/egg")
library(egg)
library(grid)

g = ggarrange(x1, x2, x3, x4, ncol = 2)
grid.newpage()
grid.draw(g)

Оригинал

Незначительное редактирование: Обновление кода.

Если вы хотите сохранить метки оси, затем с помощью какого-то скриптового и заимствования кода здесь, это делает работу.

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

# Get the widths
gA <- ggplotGrob(x1)
gB <- ggplotGrob(x2)
gC <- ggplotGrob(x3)
gD <- ggplotGrob(x4)
maxWidth = unit.pmax(gA$widths[2:3], gB$widths[2:3], 
                     gC$widths[2:3], gD$widths[2:3])

# Set the widths
gA$widths[2:3] <- maxWidth
gB$widths[2:3] <- maxWidth
gC$widths[2:3] <- maxWidth
gD$widths[2:3] <- maxWidth

# Arrange the four charts
grid.arrange(gA, gB, gC, gD, nrow=2)

enter image description here

АЛЬТЕРНАТИВНЫЕ РЕШЕНИЯ: В пакете gtable есть функции rbind и cbind для объединения гномов в один grob. Для диаграмм здесь ширины должны быть установлены с помощью size = "max", но версия CRAN gtable выдает ошибку.

Один из вариантов - изучить график grid.arrange, а затем использовать параметры size = "first" или size = "last" `:

# Get the ggplot grobs
gA <- ggplotGrob(x1)  
gB <- ggplotGrob(x2)
gC <- ggplotGrob(x3)
gD <- ggplotGrob(x4)

# Arrange the four charts
grid.arrange(gA, gB, gC, gD, nrow=2)

# Combine the plots   
g = cbind(rbind(gA, gC, size = "last"), rbind(gB, gD, size = "last"), size = "first")

# draw it
grid.newpage()
grid.draw(g)

Второй вариант - bind функции из пакета gridExtra.

# Get the ggplot grobs
gA <- ggplotGrob(x1)  
gB <- ggplotGrob(x2)
gC <- ggplotGrob(x3)
gD <- ggplotGrob(x4)

# Combine the plots
g = cbind.gtable(rbind.gtable(gA, gC, size = "max"), rbind.gtable(gB, gD, size = "max"), size = "max")

# Draw it
grid.newpage()
grid.draw(g)

Ответ 3

Именно та проблема, для которой я написал пакет cowplot. Это можно сделать в одной строке в этом пакете:

require(cowplot) # loads ggplot2 as dependency
# re-create the four plots
A <- c(1,5,6,7,9)
B <- c(10,56,64,86,98)
C <- c(2001,3333,5678,4345,5345)
D <- c(13446,20336,24333,34345,42345)
L <- c(20,34,45,55,67)
M <- data.frame(L, A, B, C, D)
x1 <- ggplot(M, aes(L, A,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x2 <- ggplot(M, aes(L, B,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x3 <- ggplot(M, aes(L, C,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')
x4 <- ggplot(M, aes(L, D,xmin=10,ymin=0)) + geom_point() + stat_smooth(method='lm')

# arrange into grid and align
plot_grid(x1, x2, x3, x4, align='vh')

Это результат: enter image description here (Обратите внимание, что cowplot изменяет тему ggplot2 по умолчанию. Вы можете получить серый, хотя если вы действительно этого хотите.)

В качестве бонусной функции вы также можете добавить метки графика в верхнем левом углу каждого графика:

plot_grid(x1, x2, x3, x4, align='vh', labels=c('A', 'B', 'C', 'D'))

Результат: enter image description here

Я использую параметр labels практически для каждого многочастного графика, который я делаю.

Ответ 4

Patchwork - это новый пакет, который упрощает форматирование и компоновку нескольких ggplots. Одна из лучших вещей в том, что он автоматически выравнивает области сюжета. Кроме того, синтаксис очень прост.

devtools::install_github("thomasp85/patchwork")
library(patchwork)
x1 + x2 + x3 + x4 + plot_layout(ncol = 2)

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

Зайдите на страницу GitHub для получения дополнительных примеров: https://github.com/thomasp85/patchwork

Ответ 5

Если вы используете RMarkdown и вязание в PDF, у меня есть альтернативный подход.  Knrit предлагает функциональные возможности субфигуры сюжета при создании PDF файла, который позволяет вам иметь несколько фигур на сюжете, каждый со своей собственной подписью.

Чтобы это сработало, каждый график должен отображаться отдельно. Объединив несколько функций из пакета cowplot, я сделал следующую функцию, которая выравнивает графики, сохраняя их как отдельные объекты:

plot_grid_split <- function(..., align = "hv", axis= "tblr"){
  aligned_plots <- cowplot::align_plots(..., align=align, axis=axis)
  plots <- lapply(1:length(aligned_plots), function(x){
    cowplot::ggdraw(aligned_plots[[x]])
  })
  invisible(capture.output(plots))
}

Вот пример, сравнивающий макет обычно с помощью функции:

---
output: pdf_document
header-includes:
   - \usepackage{subfig}
---

```{r}
plot_grid_split <- function(..., align = "hv", axis= "tblr"){
  aligned_plots <- cowplot::align_plots(..., align=align, axis=axis)
  plots <- lapply(1:length(aligned_plots), function(x){
    cowplot::ggdraw(aligned_plots[[x]])
  })
  invisible(capture.output(plots))
}
```

```{r fig-sub, fig.cap='Four Plots Not Aligned', fig.subcap=c('Plot One', 'Plot Two', 'Plot Three', 'Plot Four'), out.width='.49\\linewidth', fig.asp=1, fig.ncol = 2}  
library(ggplot2) 
plot <- ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) +
  geom_point()

plot + labs(title = "A nice title")
plot + labs(caption = "A sample caption")
plot + theme(legend.position = "none")
plot + theme(legend.position = "top")
```  

```{r fig-sub-2, fig.cap='Four Plots Aligned', fig.subcap=c('Plot One', 'Plot Two', 'Plot Three', 'Plot Four'), out.width='.49\\linewidth', fig.asp=1, fig.ncol = 2}

x1 <- plot + labs(title = "A nice title")
x2 <- plot + labs(caption = "A sample caption")
x3 <- plot + theme(legend.position = "none")
x4 <- plot + theme(legend.position = "top")

plot_grid_split(x1, x2, x3, x4)
```

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

  • Вы можете узнать больше о субфигурах в R в этом сообщении.
  • Кроме того, вы можете проверить параметры knitr, чтобы узнать больше о параметрах chunk для субфигур: https://yihui.name/knitr/options/