ggplot:使用RColorBrewer软件包填充Boxplots +使用R Cowxlot软件包中的plot_grid()绘制Boxplots

时间:2019-02-02 05:31:43

标签: r ggplot2 graphics boxplot cowplot

概述

我有两个名为'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”)<遵循此example RColorBrewer 包中找到/ strong>即可产生所需的结果。但是,我的代码无效(请参见下图)。

  • 当我在 Cowplot包中使用 plot_grid()绘制箱形图时,标签标题的位置(即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 :(得分:2)

  1. scale_fill_brewer(palette = "Dark2")在您的示例中不起作用,因为您没有提供fill-美学。您需要将其添加到箱线图中。
  2. plot_grid中的标签应为单个字母(或至少简短),以供标题中参考。为了您的目的,建议在原始图中使用标题。
  3. 您的代码很难阅读,可以减少使用的软件包数量。我还缩短了名称,因为它们在这里并不那么重要,并使所有内容都变得更加冗长。
  4. 我不会在ggplot调用中而是在单独的data.frame中计算特殊统计信息。

包装

library(tidyverse)
library(cowplot)

第一个箱形图

# 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")

第二个箱线图
类似于第一个:

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)

或者使用正确的标题和标题说明(感谢克劳斯·威尔克):

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,那没有问题。或者,您也可以按照建议操作ylimit。函数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,将上限设置为第二个数据帧中Canopy索引最大值的1.05倍。

数据

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")