我想从数据集densityAGRLKA
创建一个带有ggplot2的箱线图,在x轴上有3个分类变量(物种,位置,位置)。
以下功能:
ggplot(densityAGRLKA, aes(species, density, fill=location, alpha=position), dodge=species, position) +
stat_boxplot(geom ='errorbar') +
geom_boxplot()
创建一个情节,其中物种的分组很好,但颜色是误导。我不知道如何解决这个问题。
我需要一个具有以下属性的图:
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")
答案 0 :(得分:7)
以下是三个逐步涉及的选项,用于以您在问题中描述的方式添加文本,然后使用分面的不同方法:
首先,创建一些我们稍后会使用的实用值:
# 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)
现在创建一个基本的boxplot。我们使用interaction
函数根据location
和position
的所有组合创建填充美学:
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)
现在这个盒子图有五种变体。三个基于您的问题中的请求和基于分面的两个备选方案:
p + labs(fill="Location-Position") +
theme(legend.position="bottom")
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)
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)
下面的代码相对简单,但我并不认为分面的方式导致重复标签,而不是在连续的方面重复相同级别两次或四次时使用单个生成标签。以下是"标准" ggplot faceting。接下来是将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="")
要更改构面标签以使单个标签跨越给定类别(而不是对每个构面重复使用相同的标签),需要超出ggplot并使用较低级别的网格函数来更改构面条带标签。这是一个例子:
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)