使用带标签的地毯图绘制ggplot2箱线图

16

我能用ggplot2制作这样的图吗?

# data
require(vegan)
data(dune)
data(dune.env)

# RDA
RDA <- rda(dune ~ A1, data = dune.env)

# extract species scores
df <- data.frame(spec_scores = scores(RDA)$species[ , 1], 
                 taxa = rownames(scores(RDA)$species))
df <- df[abs(df$spec_scores) > 0.05, ]

# plot
par(mar = c(5,4,4,8))
# boxplot of sites-scores along A1-axis
boxplot(scores(RDA)$sites[ , 1] ~ dune.env$Management)
abline(h = 0, lty = "dotted")

# add species scores to plot
rug(df$spec_scores, side=4)
linestack(df$spec_scores, labels=df$taxa, at = par("usr")[2], add = TRUE, hoff = 1)

enter image description here

我基本上正在寻找一种在箱线图下方绘制标记地毯图的方法。

有什么提示或建议吗?


我认为这需要一些特定的网格技巧来安排文本,使其放置在绘图区域之外,并连接标签与刻度线段。如果您有什么想法或得到了回应,我会很感兴趣,因为我刚刚迈出了一个名为ggvegan的软件包的第一步,它希望(最终)提供vegan中所有绘图函数的ggplot版本。 - Gavin Simpson
1
@Gavin Simpson:好主意!我也用ggplot2绘制排序图表。还有github上的phyloseq。你的项目在github上吗(方便协作)? - EDi
还没有,但很快就会了。我打算把这个放在Github上并同步到R-forge。任何贡献都将不胜感激。那些试探性的步骤主要是在我的脑海中进行的,以及一些探索性的代码调查autoplot()。还需要一些头脑风暴 - 只是生成图形还是返回一个有用的对象?等等。 - Gavin Simpson
2个回答

16

这仅使用ggplot2进行解决,因此不会是最优雅的解决方案。

我开始按照@Eric Fail的建议进行第一步。

require(vegan)
data(dune)
data(dune.env)

# RDA
RDA <- rda(dune ~ A1, data = dune.env)

# extract species scores
df1 <- data.frame(RDA.scores = scores(RDA)$sites[ , 1], Management = dune.env$Management)
df2 <- data.frame(y = scores(RDA)$species[ , 1], taxa = rownames(scores(RDA)$species))
# Order data according to species scores
df2<-df2[order(df2$y),]

# define values for rugs (segments). 4.9 and 5.0 used because data has 4 levels (+1)
df2$x=4.9
df2$xend=5

# define coordinates for names (30 is number of species)
df2$yend2<-seq(min(df1$RDA.scores),max(df1$RDA.scores),length.out=30)
df2$xend2=5.3

# plot
P <- ggplot(data = df1, aes( x = Management, y = RDA.scores) ) + 
     geom_segment(y=0,yend=0,x=0,xend=5, lty=2, size = I(0.3)) + 
     geom_boxplot() + 
     #add extra levels to get space
     scale_x_discrete(limits=c("BF", "HF", "NM", "SF", "","")) + 
     #set y scale
     scale_y_continuous(limits=c(-3,5),expand=c(0,0)) +
     #add rugs as segments and add segments connecting rugs and texts
     geom_segment(data= df2, mapping=aes(x=x,xend=xend,y=y,yend=y), size = I(0.3)) +
     geom_segment(data= df2, mapping=aes(x=xend,xend=xend2,y=y,yend=yend2), size = I(0.4)) +
     #add texts
     geom_text(data=df2,mapping=aes(x=xend2+0.1,y=yend2,label=taxa),hjust=0, size=3) +
     #add rectangular to imitate box around plot
     geom_rect(xmax=5,xmin=0.4,ymax=5,ymin=-3,colour="black",fill=NA)

# Final adjustments of plot
P+theme(axis.line=element_blank(),
        panel.grid=element_blank(),
        panel.background=element_blank())

ggplot2 箱线图


+1 很棒的东西。我打算在我正在编写的 ggvegan 包中借鉴这个。 - Gavin Simpson

4

我已经开始着手解决这个问题,但是卡住了。我希望发布出来,并期望那些专业数据可视化人士能为此做出贡献(如果这不是正确的方法,请告知我,我会删除这个半成品项目)。

# data
require(vegan)
data(dune)
data(dune.env)

# RDA
RDA <- rda(dune ~ A1, data = dune.env)

# extract species scores
df1 <- data.frame(RDA.scores = scores(RDA)$sites[ , 1], Management = dune.env$Management)
df2 <- data.frame(spec_scores = scores(RDA)$species[ , 1], taxa = rownames(scores(RDA)$species))
df2 <- df2[abs(df2$spec_scores) > 0.05, ]
df2 <- cbind(df2, x = rep(1:4, 6))

# plot
P <- ggplot(data = df1, aes( x = Management, y = RDA.scores) ) + geom_boxplot() + theme_bw()  +geom_hline(y=0, lty=2) + geom_rug(data= df2, mapping=aes(x = x , y = spec_scores), sides="r") + geom_text(data= df2, mapping=aes(x=5, y=spec_scores, label=taxa), size=2) + xlim(c("BF", "HF", "NM", "SF", ""))
P

half-baked project plot


2
我相信这篇帖子可以帮助我们解决问题。 - Eric Fail
2
使用您的解决方案作为起点,添加了我的有关此情节的想法。 - Didzis Elferts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接