Несколько графиков в цикле без учета номинала

Я пытаюсь создать 10 пар графиков с несколькими парами графиков на страницу, и я использую цикл for для построения пар. Однако графики отправляются на устройство как отдельные графики, а не страницы.

MWE ниже имеет идентичные конструкции для базовой графики и ggplot версий, но базовая графика работает, а ggplot - нет. Что мне нужно сделать, чтобы нумерация страниц во второй версии была правильной?

library(ggplot2)
attach(mtcars)

# correct configuration
par(mfrow=c(2,2))
for (ii in 1:3){
  vars <- c("wt", "disp", "wt")
  plot(get(vars[ii]), mpg)
  hist(get(vars[ii]))
}

# places each on separate plot
par(mfrow=c(2,2))
for (ii in 1:3){
  vars <- c("wt", "disp", "wt")
  p <- ggplot(mtcars, aes(get(vars[ii]), mpg)) + geom_point(size=4)
  plot(p)
  p <- ggplot(mtcars, aes(get(vars[ii]))) + geom_histogram()
  plot(p)
}

detach(mtcars)

person JenB    schedule 19.06.2018    source источник
comment
par не работает с ggplot графикой, только с базой R. Вы вместо этого хотите фасетировать графики?   -  person camille    schedule 19.06.2018
comment
Потенциальной альтернативой фасетам может быть gridExtra::grid.arrange; см. например этот пост.   -  person Maurits Evers    schedule 19.06.2018
comment
Приятно знать, что par недоступен. Это не facet проблема - разные сюжеты. Мне нужно будет посмотреть, смогу ли я сделать gridExtra::grid.arrange или cowplot::plot_grid достаточно гибким, чтобы иметь дело с отказом от именования отдельных участков.   -  person JenB    schedule 19.06.2018
comment
Вы можете попробовать сохранить свои графики в списке для работы с упомянутыми вами пакетами / функциями.   -  person aosmith    schedule 19.06.2018


Ответы (1)


Вот один из способов сделать это с cowplot::plot_grid. Функция plot_duo использует подход tidyeval в ggplot2 v3.0.0

# install.packages("ggplot2", dependencies = TRUE)

library(rlang)
library(dplyr)
library(ggplot2)
library(cowplot)

plot_duo <- function(df, plot_var_x, plot_var_y) {

  if (is.character(plot_var_x)) {
    print('character column names supplied, use ensym()')
    plot_var_x <- ensym(plot_var_x)
  } else {
    print('bare column names supplied, use enquo()')
    plot_var_x <- enquo(plot_var_x)
  }

  if (is.character(plot_var_y)) {
    plot_var_y <- ensym(plot_var_y)
  } else {
    plot_var_y <- enquo(plot_var_y)
  }

  pts_plt <- ggplot(df, aes(x = !! plot_var_x, y = !! plot_var_y)) + geom_point(size = 4)
  his_plt <- ggplot(df, aes(x = !! plot_var_x)) + geom_histogram()

  duo_plot <- plot_grid(pts_plt, his_plt, ncol = 2)
}

### use character column names
plot_vars1 <- c("wt", "disp", "wt")
plt1 <- plot_vars1 %>% purrr::map(., ~ plot_duo(mtcars, .x, "mpg"))
#> [1] "character column names supplied, use ensym()"
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> [1] "character column names supplied, use ensym()"
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> [1] "character column names supplied, use ensym()"
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

plot_grid(plotlist = plt1, nrow = 3)

### use bare column names
plot_vars2 <- alist(wt, disp, wt)
plt2 <- plot_vars2 %>% purrr::map(., ~ plot_duo(mtcars, .x, "mpg"))
#> [1] "bare column names supplied, use enquo()"
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> [1] "bare column names supplied, use enquo()"
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> [1] "bare column names supplied, use enquo()"
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

plot_grid(plotlist = plt2, nrow = 3)

Чтобы разделить графики на несколько страниц, мы можем использовать gridExtra :: marrangeGrob

ml1 <- marrangeGrob(plt, nrow = 2, ncol = 1)

# Interactive use
ml1

# Non-interactive use, multipage pdf
ggsave("multipage.pdf", ml1)
person Tung    schedule 19.06.2018
comment
Спасибо. Это почти работает. В моем MWE вы можете видеть, что я генерирую 6 графиков с 2x2 для первой «страницы» и 2x1 для второй. Я адаптировал ваш код к своим реальным данным, но do.call размещает все графики на одной странице. Есть ли способ установить ограничение 2x2, чтобы для каждых 4 подзаговоров создавался отдельный график? - person JenB; 19.06.2018