ggplot2:boxplot,颜色和文本标签映射到两个分类变量的组合

oli*_*oli 6 r legend labels ggplot2 boxplot

我想从数据集创建一个带有ggplot2的箱线图,该数据集densityAGRLKA在x轴上有3个分类变量(物种,位置,位置).

以下功能:

ggplot(densityAGRLKA, aes(species, density, fill=location, alpha=position), dodge=species, position) + 
stat_boxplot(geom ='errorbar') + 
geom_boxplot() 
Run Code Online (Sandbox Code Playgroud)

创造了一个情节,其中物种的分组很好,但颜色是误导.我不知道如何解决这个问题.

我需要一个具有以下属性的图:

  • 数据按分组 species
  • 在集团内location,
  • 并在顺序的位置内top,然后bottom.

另外,如果location将它们写在属于一起的两个盒子position下面,并且在每个盒子下面,那就太棒了.或者更好的着色/阴影框然后提供一个清晰的传奇?

样本数据:

densityAGRLKA = structure(list(location = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L), .Label = c("SF", "SS"), class = "factor"), species = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("AGR", "LKA"), class = "factor"), 
        position = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
        2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 
        1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
        2L), .Label = c("top", "bottom"), class = "factor"), density = c(0.41, 
        0.41, 0.43, 0.33, 0.35, 0.43, 0.34, 0.46, 0.32, 0.32, 0.4, 
        0.4, 0.45, 0.34, 0.39, 0.39, 0.31, 0.38, 0.48, 0.3, 0.42, 
        0.34, 0.35, 0.4, 0.38, 0.42, 0.36, 0.34, 0.46, 0.38, 0.36, 
        0.39, 0.38, 0.39, 0.39, 0.39, 0.36, 0.39, 0.51, 0.38)), .Names = c("location", 
    "species", "position", "density"), row.names = c(NA, -40L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)

eip*_*i10 8

以下是三个逐步更复杂的选项,用于按照您在问题中描述的方式添加文本,然后使用分面的不同方法:

建立

首先,创建一些我们稍后将使用的实用值:

# Color vectors
LocPosCol = c(hcl(0,100,c(50,80)), hcl(240,100,c(50,80)))
LocCol = c(hcl(c(0,240),100,65))

# Dodge width
pd = position_dodge(0.7)
Run Code Online (Sandbox Code Playgroud)

现在创建一个基本的boxplot.我们使用interaction功能基础上的所有组合来创建一个填充的审美locationposition:

p = ggplot(densityAGRLKA, 
           aes(species, density, 
               fill=interaction(location, position, sep="-", lex.order=TRUE))) + 
  geom_boxplot(width=0.7, position=pd) + 
  theme_bw() +
  scale_fill_manual(values=LocPosCol)
Run Code Online (Sandbox Code Playgroud)

现在这个盒子图有五种变化.三个基于您的问题中的请求和基于分面的两个备选方案:

沿着底部的传说

p + labs(fill="Location-Position") +
  theme(legend.position="bottom")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在框下面有文本标识符

library(dplyr)

p + geom_text(data=densityAGRLKA %>% group_by(species, location, position) %>%
                     summarise(value=unique(paste(location, position, sep="-"))),
              aes(label=value, y=0.29, 
                  color=interaction(location, position, sep="-", lex.order=TRUE)),
              position=pd, size=3.3, fontface="bold") +
  scale_color_manual(values=LocPosCol) +
  guides(color=FALSE, fill=FALSE)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在框下面有两级文本标识符

p + geom_text(data=densityAGRLKA %>% group_by(species, location) %>% 
                     summarise %>% mutate(position=NA),
              aes(label=location, color=location, y=0.29),
              position=pd, size=4.2, fontface="bold") +
    geom_text(data=densityAGRLKA %>% group_by(species, position, location) %>% 
                     summarise,
              aes(label=position, 
                  color=interaction(location, position, sep="-", lex.order=TRUE),
                  y=0.28),
              position=pd, size=3.7, fontface="bold") +
  scale_color_manual(values=c(LocCol[1],LocPosCol[1:2],LocCol[2],LocPosCol[3:4])) +
  guides(color=FALSE, fill=FALSE)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

面对标准的ggplot facet标签

下面的代码相对简单,但是我并不喜欢分面重复标签的方式,而不是在连续方面重复相同级别两次或四次时使用单个生成标签.下面是"标准"ggplot分面.接下来是将facet标签更改为跨越多个方面的(有点痛苦)过程的示例.

ggplot(densityAGRLKA, aes("", density)) + 
  geom_boxplot(width=0.7, position=pd) + 
  theme_bw() +
  facet_grid(. ~ species + location +  position) +
  theme(panel.margin=unit(0,"lines"),
        panel.border=element_rect(color="grey90"),
        axis.ticks.x=element_blank()) +
  labs(x="")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

面对跨越给定类别的单个构面标签

要改变所述小标签,这样一个单一标记跨越给定类别(而不是重复每个小面相同的标签)需要去ggplot的外部,并使用较低的水平网格函数来改变所述小条标签grobs.这是一个例子:

library(gtable)
library(grid)

p=ggplot(densityAGRLKA, aes("", density)) + 
  geom_boxplot(width=0.7, position=pd) + 
  theme_bw() +
  facet_grid(. ~ species + location +  position) +
  theme(panel.margin=unit(0,"lines"),
        strip.background=element_rect(color="grey30", fill="grey90"),
        panel.border=element_rect(color="grey90"),
        axis.ticks.x=element_blank()) +
  labs(x="")

pg = ggplotGrob(p)

# Add spanning strip labels for species
pos = c(4,11)    
for (i in 1:2) {
  pg <- gtable_add_grob(pg, 
                        list(rectGrob(gp=gpar(col="grey50", fill="grey90")),
                             textGrob(unique(densityAGRLKA$species)[i], 
                                      gp=gpar(cex=0.8))), 3,pos[i],3,pos[i]+7,
                        name=c("a","b"))
}

# Add spanning strip labels for location
pos=c(4,7,11,15)
for (i in 1:4) {
    pg = gtable_add_grob(pg, 
                         list(rectGrob(gp = gpar(col="grey50", fill="grey90")),
                              textGrob(rep(unique(densityAGRLKA$location),2)[i], 
                                       gp=gpar(cex=0.8))), 4,pos[i],4,pos[i]+3, 
                         name = c("c", "d"))
}

plot(pg)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述