ggplot: заполнение блокпостов с помощью пакета RColorBrewer + Plot Boxplots с использованием plot_grid () в пакете Cowplot в R - PullRequest
0 голосов
/ 02 февраля 2019

Обзор

У меня есть два фрейма данных с именами 'ANOVA.Dataframe.1' и 'ANOVA.Dataframe.2' (увидеть ниже).

В этом проекте у меня две цели:

(1) Заполнить поля с помощью пакета RColorBrewer ;

(2) Нанесите на график коробки с помощью пакета Cowplot

Проблемы

  • В первом случае я создал два объектаназывается New.filled.Boxplot.obs1.Canopy.Urban , и New.filled.Boxplot.obs2.Canopy.Urban , и я добавил функцию (т.е. функцию 1или функция 2 - см. R-код ниже) , который сгенерировал коробочные диаграммы с функцией scale_fill_brewer (palette = "Dark2") , найденной в пакете RColorBrewer , следуя этому пример для получения желаемых результатов.Однако мой код не работал (см. Изображение ниже).

  • Когда я строил диаграммы с использованием plot_grid () в Пакет Cowplot , расположение заголовков этикеток (т. Е. A: Период наблюдения 1 или B: Период наблюдения 2 - см. Изображение ниже) перекрывают оба поля (см. Изображение ниже).Есть ли способ манипулировать пространством печати в окне графика, чтобы боксы были немного меньше, а заголовки надписей располагались над каждым блокпостом?

Если кто-то может помочь, я был бы очень признателен.

R-код

library(tidyverse)
library(wrapr)
library(RColorBrewer)
library(dplyr)

# Open Colour Brewer Paletter Options
display.brewer.all()


## Function 1 to produce the boxplots for Dataframe 1

Boxplot.obs1.Canopy.Urban<-ANOVA.Dataframe.1 %.>%
                                   ggplot(data = ., aes(
                                   x = Urbanisation_index,
                                   y = Canopy_Index,
                                   group = Urbanisation_index,
                                   )) +
                                   stat_boxplot(
                                   geom = 'errorbar',
                                   width = .25
                                   ) +
                                   geom_boxplot(notch=T) +
                                   geom_line(
                                   data = group_by(., Urbanisation_index) %>%
                                   summarise(
                                   bot = min(Canopy_Index),
                                   top = max(Canopy_Index)
                                    ) %>%
                                   gather(pos, val, bot:top) %>% 
                                   select(
                                   x = Urbanisation_index,
                                   y = val
                                   ) %>%
                                   mutate(gr = row_number()) %>%
                                   bind_rows(
                                   tibble(
                                   x = 0,
                                   y = max(.$y) * 1.15,
                                   gr = 1:8
                                   )
                                   ),
                                  aes(
                                  x = x,
                                  y = y,
                                  group = gr
                                  )) +
                                  theme_light() +
                                  theme(panel.grid = element_blank()) +
                                  coord_cartesian(
                                  xlim = c(min(.$Urbanisation_index) - .5, max(.$Urbanisation_index) + .5),
                                  ylim = c(min(.$Canopy_Index) * .95, max(.$Canopy_Index) * 1.05)
                                   ) +
                                 ylab('Company Index (%)') +
                                 xlab('Urbanisation Index')

 ## Change the colours of the boxplot
New.filled.Boxplot.obs1.Canopy.Urban <- Boxplot.obs1.Canopy.Urban + scale_fill_brewer(palette="Dark2")

## Function 2 to produce the boxplots for Dataframe 2
Boxplot.obs2.Canopy.Urban<-ANOVA.Dataframe.2 %.>%
                                   ggplot(data = ., aes(
                                   x = Urbanisation_index,
                                   y = Canopy_Index,
                                   group = Urbanisation_index,
                                   )) +
                                   stat_boxplot(
                                   geom = 'errorbar',
                                   width = .25
                                   ) +
                                   geom_boxplot(notch=T) +
                                   geom_line(
                                   data = group_by(., Urbanisation_index) %>%
                                   summarise(
                                   bot = min(Canopy_Index),
                                   top = max(Canopy_Index)
                                    ) %>%
                                   gather(pos, val, bot:top) %>% 
                                   select(
                                   x = Urbanisation_index,
                                   y = val
                                   ) %>%
                                   mutate(gr = row_number()) %>%
                                   bind_rows(
                                   tibble(
                                   x = 0,
                                   y = max(.$y) * 1.15,
                                   gr = 1:8
                                   )
                                   ),
                                  aes(
                                  x = x,
                                  y = y,
                                  group = gr
                                  )) +
                                  theme_light() +
                                  theme(panel.grid = element_blank()) +
                                  coord_cartesian(
                                  xlim = c(min(.$Urbanisation_index) - .5, max(.$Urbanisation_index) + .5),
                                  ylim = c(min(.$Canopy_Index) * .95, max(.$Canopy_Index) * 1.05)
                                   ) +
                                 ylab('Company Index (%)') +
                                 xlab('Urbanisation Index')


## Change the colours of the boxplot

 New.filled.Boxplot.obs2.Canopy.Urban<- Boxplot.obs2.Canopy.Urban + scale_fill_brewer(palette="Dark2")

library(cowplot)

## Open New plot window
dev.new()

Combined_boxplot_Obs<-plot_grid(New.filled.Boxplot.obs1.Canopy.Urban, 
                                New.filled.Boxplot.obs2.Canopy.Urban, 
                                labels=c("A: Observation Period 1",
                                         "B: Observation Period 2"),
                                label_fontface="bold",
                                label_fontfamily="Times New Roman",
                                label_size=12,
                                align="v",
                                ncol=2, nrow=1)

Combined_boxplot_Obs

Этот R-код производит следующие графики:

enter image description here

Фрейм данных 1

structure(list(Urbanisation_index = c(2, 2, 4, 4, 3, 3, 4, 4, 
4, 2, 4, 3, 4, 4, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 
2, 2, 2, 4, 4, 3, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 4, 4, 4, 
4, 4, 4, 4), Canopy_Index = c(65, 75, 55, 85, 85, 85, 95, 85, 
85, 45, 65, 75, 75, 65, 35, 75, 65, 85, 65, 95, 75, 75, 75, 65, 
75, 65, 75, 95, 95, 85, 85, 85, 75, 75, 65, 85, 75, 65, 55, 95, 
95, 95, 95, 45, 55, 35, 55, 65, 95, 95, 45, 65, 45, 55)), row.names = c(NA, 
-54L), class = "data.frame")

Фрейм данных 2

structure(list(Urbanisation_index = c(2, 2, 4, 4, 3, 3, 4, 4, 
4, 3, 4, 4, 4, 4, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 
2, 2, 2, 4, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 4, 4, 4, 4, 4, 4, 4
), Canopy_Index = c(5, 45, 5, 5, 5, 5, 45, 45, 55, 15, 35, 45, 
5, 5, 5, 5, 5, 5, 35, 15, 15, 25, 25, 5, 5, 5, 5, 5, 5, 15, 25, 
15, 35, 25, 45, 5, 25, 5, 5, 5, 5, 55, 55, 15, 5, 25, 15, 15, 
15, 15)), row.names = c(NA, -50L), class = "data.frame")

1 Ответ

0 голосов
/ 02 февраля 2019
  1. scale_fill_brewer(palette = "Dark2") не работает в вашем примере, потому что вы не предоставляете fill -эстетику.Вы должны добавить это к вашему боксу.
  2. Метки в plot_grid предназначены для обозначения отдельных букв (или, по крайней мере, коротких) для ссылки в заголовке.Для вашей цели я бы рекомендовал использовать заголовки на оригинальных сюжетах.
  3. Ваш код довольно сложно прочитать, и вы можете уменьшить количество используемых пакетов.Я также сокращаю название, так как они здесь не так важны и делают все более многословным.
  4. Я бы вычислял специальную статистику не внутри ggplot -колла, а до этого в отдельном data.frame.

Пакеты

library(tidyverse)
library(cowplot)

1-й Boxplots

# Calculate special positions for lines first
mydf.1.lines <- mydf.1 %>% 
  group_by(Urbanisation) %>%
  summarise(bot = min(Canopy), top = max(Canopy)) %>%
  gather(pos, val, bot:top) %>% 
  select(x = Urbanisation, y = val) %>%
  mutate(gr = row_number()) %>%
  bind_rows(tibble(x = 0, y = max(.$y) * 1.15, gr = 1:8))

# Calculate plot limits 
xlimits.1 <- with(mydf.1, c(min(Urbanisation) - .5, max(Urbanisation) + .5))
ylimits.1 <- with(mydf.1, c(min(Canopy) * .95, max(Canopy) * 1.05))

Boxplot.1 <- 
  ggplot(mydf.1, aes(Urbanisation, Canopy, group = Urbanisation)) +
  stat_boxplot(geom = 'errorbar', width = .25) +
  # Add a fill aesthetics in the geom_boxplot - call:
  geom_boxplot(aes(fill = factor(Urbanisation)), notch = TRUE) +
  geom_line(data = mydf.1.lines, 
            aes(x, y, group = gr)) +
  theme_light() +
  theme(panel.grid = element_blank()) +
  coord_cartesian(xlim = xlimits.1, ylim = ylimits.1) +
  ylab('Company Index (%)') +
  xlab('Urbanisation Index')

New.filled.Boxplot.1 <- Boxplot.1 + scale_fill_brewer(palette = "Dark2")

2nd Boxplots
Аналог 1-го:

mydf.2.lines <- mydf.2 %>% 
  group_by(Urbanisation) %>%
  summarise(bot = min(Canopy), top = max(Canopy)) %>%
  gather(pos, val, bot:top) %>% 
  select(x = Urbanisation, y = val) %>%
  mutate(gr = row_number()) %>%
  bind_rows(tibble(x = 0, y = max(.$y) * 1.15, gr = 1:8))

xlimits.2 <- with(mydf.2, c(min(Urbanisation) - .5, max(Urbanisation) + .5))
ylimits.2 <- with(mydf.2, c(min(Canopy) * .95, max(Canopy) * 1.05))

Boxplot.2 <- 
  ggplot(mydf.2, aes(Urbanisation, Canopy, group = Urbanisation)) +
  stat_boxplot(geom = 'errorbar', width = .25) +
  geom_boxplot(aes(fill = factor(Urbanisation)), notch = TRUE) +
  geom_line(data = mydf.2.lines, 
            aes(x, y, group = gr)) +
  theme_light() +
  theme(panel.grid = element_blank()) +
  coord_cartesian(xlim = xlimits.2, ylim = ylimits.2) +
  ylab('Company Index (%)') +
  xlab('Urbanisation Index')

New.filled.Boxplot.2 <- Boxplot.2 + scale_fill_brewer(palette = "Dark2")

Комбинированные графики

plot_grid(New.filled.Boxplot.1 + ggtitle("A: Observation Period 1"),
          New.filled.Boxplot.2 + ggtitle("B: Observation Period 2"), 
          align = "v",
          ncol = 2,
          nrow = 1)

Или с правильной спецификацией заголовка и hjust (Спасибо Клаусу Вилке):

plot_grid(New.filled.Boxplot.1 + ggtitle(""),
          New.filled.Boxplot.2 + ggtitle(""), 
          align = "v",
          labels = c("A: Observation Period 1", "B: Observation Period 2"),
          hjust = 0, 
          label_x = 0.01,
          ncol = 2,
          nrow = 1)

enter image description here

Бокс-поле за пределами участка
Проблема заключается в том, что выемки находятся за пределами петель.Если вы установите notch = FALSE для второго графика (или обоих), это не проблема.В качестве альтернативы вы также можете манипулировать ylimits, как вы уже предложили.Функция with просто указывает data.frame (mydf.2), в котором можно найти следующие столбцы.Таким образом, вызов

ylimits.2 <- with(mydf.2, c(min(Canopy) * .95, max(Canopy) * 1.05))

эквивалентен

ylimits.2 <- c(min(mydf.2$Canopy) * .95, max(mydf.2$Canopy) * 1.05)

, и вы можете, например, указать

ylimits.2 <- c(-20, max(mydf.2$Canopy) * 1.05)

Это установит нижний предел на -20 иверхний предел в 1,05 раза превышает максимум индекса Canopy во втором кадре данных.

Данные

mydf.1 <- 
  structure(list(Urbanisation = c(2, 2, 4, 4, 3, 3, 4, 4, 4, 2, 4, 3, 4, 4, 1, 
                                  1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 
                                  2, 2, 4, 4, 3, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 
                                  2, 1, 4, 4, 4, 4, 4, 4, 4), 
                 Canopy = c(65, 75, 55, 85, 85, 85, 95, 85, 85, 45, 65, 75, 75, 
                            65, 35, 75, 65, 85, 65, 95, 75, 75, 75, 65, 75, 65, 
                            75, 95, 95, 85, 85, 85, 75, 75, 65, 85, 75, 65, 55, 
                            95, 95, 95, 95, 45, 55, 35, 55, 65, 95, 95, 45, 65, 
                            45, 55)), 
            row.names = c(NA, -54L), class = "data.frame")

mydf.2 <- 
  structure(list(Urbanisation = c(2, 2, 4, 4, 3, 3, 4, 4, 4, 3, 4, 4, 4, 4, 1, 
                                  1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 
                                  2, 2, 4, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 4, 4, 
                                  4, 4, 4, 4, 4), 
                 Canopy = c(5, 45, 5, 5, 5, 5, 45, 45, 55, 15, 35, 45, 5, 5, 5, 
                            5, 5, 5, 35, 15, 15, 25, 25, 5, 5, 5, 5, 5, 5, 15, 
                            25, 15, 35, 25, 45, 5, 25, 5, 5, 5, 5, 55, 55, 15, 
                            5, 25, 15, 15, 15, 15)), 
            row.names = c(NA, -50L), class = "data.frame")
...