查看原文
其他

R语言绘制三元图(Ternary Plot)示例

生信小白鱼 鲤小白 小白鱼的生统笔记 2022-05-08
微生物群落分析中的三元图在R中的几种绘制方法示例

本篇分享Ternary Plot(三元相图,三元图)在R语言中的绘制方法。

示例作图数据可在如下百度盘中获取(提取码qwk7)。https://pan.baidu.com/s/11_zOvnT-ClyYyQNQ4F1xaw


三元图用一个等边三角形描述三个变量的不同属性的比率关系,并将这种比率关系映射在等边三角形的特定空间中。我们可根据重心坐标来定位图中的点,将点作垂线到三个轴上,根据垂点位置可视化三个变量之间的比率。

接下来就以一个示例来简要描述吧。如下三元图来自某微生物组相关的文献,反映了细菌OTUs在植物(Arabis alpina)根系区域的富集信息。图中,三个顶点分别代表土壤(Soil)、植物根际土壤(Rhizosphere)以及植物根组织内(Root)三种不同的根系微环境区域,每一个点表示一种OTU,点的位置由三种根系微环境对各OTU相对丰度的贡献确定,点的大小表示各OTU的相对丰度。根据各OTU在各根系微环境中的丰度数据进行统计检验后,得知各OTU分别在哪种微环境中显著富集,并据此在图中以不同颜色的点表示(土壤富集,黑色;根际区富集,红色;根内富集,绿色)。如此,各OTU的富集区域一目了然。

(出处:Root microbiota dynamics of perennial Arabis alpina are dependent on soil residence time but independent of flowering time)


在本篇,我们同样使用某16S群落测序所得的OTU数据,通过R语言绘制三元图,展示OTU的富集分布或种群类型分布。网盘文件“data.txt”为作图示例数据。其第一列(otu)为OTUs id;第2、3、4列(env1、env2、env3)分别为3个环境样本,其中的数值为各OTU在各样本中的丰度信息;第5列(rich)为通过统计检验后得到的各OTU发生显著富集的环境样本名称,例如OTU2对应env3表示OTU2在env3样本中的丰度显著高于其它两个样本,0则表示丰度无差异;第6列为各OTU所属的门分类(界门纲目科属种的“门”一级)。

首先将数据读入R中。#读取数据
dat <- read.delim('data.txt', sep = '\t', stringsAsFactors = FALSE, check.names = FALSE)接下来主要简介3种三元图作图R包。

vcd包ternaryplot()


R的vcd包中提供了绘制三元图的命令ternaryplot(),加载vcd包后使用?ternaryplot可查看帮助文档。

我们通过ternaryplot()实现三元图的绘制,如下展示一个简单示例。##ternaryplot() 三元图
library(vcd)

dat1 <- dat

#点的大小用于表示 OTUs 丰度
#由于各 OTUs 丰度差异过大,为了美观,作图时取 3 个样本的平均值的 0.4 次方再除以 10......
dat1$size <- (apply(dat1[2:4], 1, mean))^0.4 / 10

#颜色表示各 OTUs 的富集样本
dat1[which(dat1$rich == 'env1'),'color'] <- 'red'
dat1[which(dat1$rich == 'env2'),'color'] <- 'blue'
dat1[which(dat1$rich == 'env3'),'color'] <- 'green3'
dat1[which(dat1$rich == '0'),'color'] <- 'gray'

#ternaryplot() 示例,按 OTUs 富集区域着色
#pdf('ternaryplot.pdf')
png('ternaryplot.png', width = 2000, height = 2000, res = 300, units = 'px')
ternaryplot(dat1[2:4], scale = NULL, col = dat1$color, prop_size = FALSE, cex = dat1$size, main = 'Enriched OTUs')
grid_legend(x = 0.8, y = 0.7, pch = c(19, 19, 19), col = c('red', 'blue', 'green3'), label = c('env1', 'env2', 'env3'), title = FALSE, frame = FALSE)
dev.off()

ternaryplot()用起来挺方便的,效果也很不错,以上仅展示了一个简单的示例,更多作图方法大家有兴趣的话还请自行研究它了。

Ternary包TernaryPlot()


Ternary包提供了从头绘制三元图的方法,作图数据集需要分别构建,再通过TernaryPlot()、AddToTernary()等作图命令一步步绘制三元图组件。通过??Ternary可调出该包的帮助文档参阅。

接下来,我们通过Ternary包实现三元图的绘制,如下展示一个简单示例。

##TernaryPlot() 三元图
library(Ternary)

dat2 <- dat

#计算点坐标,根据变量在三个样本中的相对比率,再乘以 100,即可得到
dat2$sum <- apply(dat1[2:4], 1, sum)
dat2$env1 <- 100 * dat2$env1/dat2$sum
dat2$env2 <- 100 * dat2$env2/dat2$sum
dat2$env3 <- 100 * dat2$env3/dat2$sum

otu <- list()
for (i in 1:nrow(dat2)) {
otu[[i]] <- as.vector(unlist(dat2[i,c(2:4)]))
names(otu)[i] <- as.vector(dat2[i,1])
}

#赋值点颜色,颜色表示各 OTUs 的富集样本
dat2[which(dat2$rich == 'env1'),'color'] <- 'red'
dat2[which(dat2$rich == 'env2'),'color'] <- 'blue'
dat2[which(dat2$rich == 'env3'),'color'] <- 'green3'
dat2[which(dat2$rich == '0'),'color'] <- 'gray'

color <- c()
for (i in 1:nrow(dat2)) {
color[i] <- dat2[i,'color']
names(color)[i] <- as.vector(dat2[i,1])
}

#赋值点大小
#由于各 OTUs 丰度差异过大,为了美观,作图时取 3 个样本的平均值的 0.4 次方再除以 5......
size = c()
for (i in 1:nrow(dat2)) {
size[i] <- (apply(dat1[i,2:4], 1, mean))^0.4 / 5
names(size)[i] <- as.vector(dat2[i,1])
}

#作图
#pdf('TernaryPlot.pdf')
png('TernaryPlot.png', width = 2000, height = 2000, res = 300, units = 'px')
TernaryPlot(atip = 'env1', btip = 'env2', ctip = 'env3', col = NA, grid.col = 'gray', grid.minor.col = NA, axis.col = 'black')
AddToTernary(points, otu, col = color, cex = size, pch = 20)
dev.off()

好吧,这个包用起来有点累人,全程“手动挡”……它的可选调节参数也是非常地多,看得有点眼花,还得慢慢熟悉了。

如果你喜欢“自动挡”,那么接下来的ggtern将会特别合适。



ggtern包ggtern()


然后简介ggtern。ggtern是在ggplot2的基础上开发的,其语法和ggplot2几乎一致,且功能也像ggplot2一样的强大,因此对于习惯使用ggplot2作图的同学们(例如,我就是)肯定也会更倾向于使用ggtern绘制三元图。
接下来,我们通过ggtern绘制一个简单的三元图。##ggtern 三元图
library(ggtern)

dat3 <- dat

#点的大小用于表示 OTUs 丰度
#由于各 OTUs 丰度差异过大,为了美观,作图时取 3 个样本的平均值的 0.5 次方......
dat3$size <- (apply(dat3[2:4], 1, mean))^0.5

#ggtern,作图时按 OTUs 富集区域对点着色
p_rich <- ggtern(dat3, aes(env1, env2, env3)) +
geom_mask() +
geom_point(aes(color = rich, size = size), alpha = 0.8, show.legend = FALSE) +
scale_size(range = c(0, 6)) +
scale_colour_manual(values = c('red', 'blue', 'green3', 'gray'), limits = c('env1', 'env2', 'env3', '0')) +
theme_bw() +
theme(axis.text = element_blank(), axis.ticks = element_blank())

#ggsave('ggtern.pdf', p_rich, width = 6, height = 6)
ggsave('ggtern.png', p_rich, width = 6, height = 6)


上文均根据OTUs的富集情况,为OTUs指定颜色。然后我们此处再展示一个示例,根据OTUs所属的门类群,为OTUs(即图中的点)指定颜色。#ggtern,按 OTUs 所属门类群对点着色
#由于 OTUs 所属的门类群较多,此处不再单独定义每一类细菌门的颜色,使用 ggtern 的默认颜色
p_taxonomy <- ggtern(dat3, aes(env1, env2, env3)) +
geom_mask() +
geom_point(aes(color = taxonomy, size = size), alpha = 0.8) +
scale_size(range = c(0, 6)) +
theme_bw() +
theme(axis.text = element_blank(), axis.ticks = element_blank(), legend.title = element_blank()) +
guides(size = 'none')

p_taxonomy

作为ggplot2的延伸,ggtern的功能堪比ggplot2,因此它能绘制的图类型很多,而不仅仅局限于点图,如下展示一个很简单的密度图。#密度图举例
dens <- ggtern(dat3, aes(env1, env2, env3)) +
stat_density_tern()

dens

相信习惯ggplot2的同学门上手ggtern会很快。关于ggtern更多的功能就不再多说了,大家有兴趣的话还请自行研究它。


链接

突破韦恩图数量限制,R包UpSetR集合可视化

差异分析及显著性“abc”标记的R操作示例

R语言绘制提琴图

R语言绘制箱线图

R语言绘制双向柱状图

R语言绘制堆叠面积图

R语言绘制堆叠柱状图

R语言绘制星形图

R语言绘制圆环图

R语言绘制饼图(扇形图)

R语言绘制花瓣图

R语言绘制韦恩图




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存