Как установить размер сюжета в ggplot или ggarrange? - PullRequest
0 голосов
/ 14 апреля 2020

Я работаю с Rmarkdown и создаю множество фигур, составленных из разных диаграмм ggplot2, используя ggarrange. Я хотел бы создать функцию, чтобы все было легко. Проблема в том, что я не могу установить разные размеры для фигур внутри одного куска. Единственный способ установить размер фигуры - использовать параметры чанка, например:

{r Figure1, fig.height = 4, fig.width = 7}

Все первичные графики должны иметь тот же размер области сетки, но размер окончательных цифр изменяется в зависимости от количества основных участков, которые они содержат. Кроме того, для целей аннотации (например, с функцией annotation_figures ()) диаграммы в первой строке должны иметь большее верхнее поле (для заголовка), в то время как диаграммы в последней строке должны иметь большее нижнее поле (для подписей). Дополнительные поля, чтобы освободить место для заголовков и подписей (например, текстовых групп), не должны изменять размер сетки графика, который я хочу сделать одинаковым для всех графиков внутри фигуры.

Один пример фрейма данных под названием "A1", который у меня есть:

knitr::opts_knit$set(root.dir = "H:\\R")
knitr::opts_chunk$set(echo = TRUE)

library("pacman")
p_load(
dplyr, extrafont, GGally, ggplot2, ggthemes, ggpubr, grid,  hrbrthemes, htmlwidgets, plotly, plotrix, tidyverse)

year <- rep(seq(2010,2019, 1), each=3)
name <- rep(c("A", "B", "C"), times=10)
n1 <- c(0,0,1,0,2,1,1,1,1,2,0,2,0,2,1,3,2,0,1,4,2,2,9,4,8,11,8,7,9,8)
n2 <- c(7,3,1,14,1,1, 15,4,4,19,9,4,26,9,4,46,4,3,52,12,3,37,12,5,45,10,5,47,18,4)
name2 <- name
A1 <-data.frame(year,name,n1,n2,name2)

С помощью этого фрейма данных я строю первый ряд графиков внутри фрагмента со спецификациями {fig.height = 4.3, fig.width = 7}. Эта строка графика имеет три графика (сделанных с помощью facet_wrap) и верхнее поле 0,3 дюйма, чтобы освободить место для аннотации заголовка на последнем рисунке, и без нижнего поля. Эта строка графика также имеет собственный заголовок, который будет функционировать как подзаголовок или тег на конечном рисунке.

AA.1 <- A1 %>%
    ggplot( aes(x=year, y=n1)) +
    geom_line( data=A1 %>% dplyr::select(-name), aes(group=name2), color="grey", size=1.0, alpha=0.6) +
    geom_line( aes(color=name), color="black", size=1.5 ) + 
    theme_ipsum() +
    theme(
      axis.text.x = element_text(size=12, angle=45),
      axis.text.y = element_text(size=12),
      legend.position="none",
      plot.title = element_text(size=16),
      panel.grid = element_blank(),
      plot.margin = unit(c(0.3, 0.2, 0, 0.2), "in")) + #Top row charts have a 0.3 top margin
    labs(title="A. TAK") +
    scale_x_continuous(name ="", 
                    limits=c(2010,2019),
                breaks=c(seq(2010,2019,2)))+
    scale_y_continuous(name ="", 
                    limits=c(0,12),
                breaks=c(seq(0,12,3)))+
    facet_wrap(~name) +
    theme(strip.text = element_text(size=13))

AA.1

Затем я создаю графики нижнего ряда внутри другого фрагмента с другой спецификацией высоты фигуры: {fig.height = 4.1, fig.width = 7}. Этот ряд также состоит из трех графиков, которые должны быть похожи во всех аспектах эстетики на первый ряд, хотя я рисую другую переменную с разными значениями (ссылка). Этот ряд должен иметь верхние поля и нижнее поле 0,1 дюйма, чтобы освободить место для подписей.

AA.2 <- A1 %>%
    ggplot( aes(x=year, y=n2)) +
    geom_line( data=A1 %>% dplyr::select(-name), aes(group=name2), color="grey", size=1.0, alpha=0.6) +
    geom_line( aes(color=name), color="black", size=1.5 )+ 
    theme_ipsum() +
    theme(
      axis.text.x = element_text(size=12, angle=45),
      axis.text.y = element_text(size=12),
      legend.position="none",
      plot.title = element_text(size=16),
      panel.grid = element_blank(),
      plot.margin = unit(c(0, 0.2, 0.1, 0.2), "in")) + #Margins are different
    ggtitle("B. REF") +
    scale_x_continuous(name ="", 
                    limits=c(2010,2019),
                breaks=c(seq(2010,2019,2)))+
    scale_y_continuous(name ="", 
                    limits=c(0,60),
                breaks=c(seq(0,60,10)))+
    facet_wrap(~name) +
    theme(strip.text = element_text(size=13))
AA.2

После этого я размещаю оба набора графиков внутри фигуры с помощью ggarange () и пишу окончательный заголовок и подписи с помощью annotate_figure (). В этом чанке я установил общее значение fig.height на 8,4 (сумма двух предыдущих чанков).


figureA1 <- ggarrange(AA.1, AA.2,
                   ncol=1, nrow=2,
                   heights=c(1,1))

annotate_figure(
  figureA1,
  top = text_grob("Figura A.1 - TAK & REF",
                color = "black", face = "bold", size = 18),
  bottom = text_grob("Source: My.Data (2020)", face="italic", color = "black",
                     hjust = 1, x = 1, size = 12),)

Проблемы, с которыми я сталкиваюсь: 1. Мне бы хотелось, чтобы у каждого графика была общая площадь сетки 4 дюйма. Поскольку у первого графика верхнее поле равно 0,3, а нижнее поле равно 0, я установил на Fig.height значение 4,3. Так как второй график имеет верхнее поле 0 и нижнее поле 0,1, я установил на Fig.height значение 0,1. Тем не менее, область сетки графика, по-видимому, не имеет одинакового размера на обоих графиках. Есть какие нибудь идеи как это починить? 2. Поскольку параметры fig.height различны для каждого графика, мне нужно разделить код, чтобы построить фигуру на разные куски. У меня есть много фигур, которые сделаны подобным образом, и поэтому я хотел бы написать функцию для построения и упорядочения графиков внутри фигур. Однако я не могу написать функцию для разных кусков.

Я думаю о двух возможных решениях: 1. Какой-то способ задания размера графика сетки в функции ggplot (или общей площади графика); или 2. Каким-то образом установить каждый из размеров сетки в функции ggarrange;

Возможно, второй будет еще лучше. Я попытался установить одинаковую высоту строк в ggarrange с одинаковым аргументом heights ("heights = c (1,1)"). Также пытались сделать их пропорциональными каждому fig.height («heights = c (5.3 / 5.1,1)»), но сетка второй строки графика все еще выглядит выше, чем первая. Рисунок A1 - высота = c (5.3 / 5.1,1)

...