查看原文
其他

R语言绘制花瓣图(Flower plot)示例

鲤小白 小白鱼的生统笔记 2022-05-08


R语言绘制花瓣图(Flower plot)


    介绍完了韦恩图(Venn plot),怎么能少得了花瓣图(Flower plot)呢?花瓣图,顾名思义,因形似花瓣,称为花瓣图。相对于韦恩图,它的构造比较简单,常在较大样本/分组数量的情况下使用(样本/分组>5,此时韦恩图很难绘制),展示所有样本/分组的共有元素信息(中心交叉区域)。但是相较于韦恩图,它无法给出某几个样本/分组间的共有元素信息。

    今天呢白鱼小编继续带来R语言绘制花瓣图的方法。说到这个,相信好多同学也和本小编一样,曾经有过这么一个疑惑:“咦,我怎么找不到画花瓣图的R包呢?”韦恩图的R包虽说一找一大片,但是绘制花瓣图的R包确实很稀罕,至少本小编到现在也没找到一个……所以这回呢我们来手动搞一下。我们能看到花瓣图由“花瓣”构成,这些花瓣其实就是椭圆嘛,那么我们不妨就可以根据样本数量,设置好椭圆的角度,依次叠加椭圆以实现花瓣图的绘制。

    话不多说了,上代码。好吧其实本小编也是借鉴了某大神的方法,在其代码的基础上作了修改的,总之先感谢一波大神分享,嘿嘿。

   

#作图数据的网盘链接:https://pan.baidu.com/s/10h8VqkFE_1Z_60GxsPSX0w
#“flower.txt”,包含20个样本,我们绘制花瓣图展示它们的共有元素数量

#读入作图文件,预处理,获取样本名称,统计共有元素个数等
flower_dat <- read.delim('flower.txt', header = T, sep = '\t', stringsAsFactors = F, check.names = F)
sample_id <- colnames(flower_dat)
otu_id <- unique(flower_dat[,1])
otu_id <- otu_id[otu_id != '']
core_otu_id <- otu_id
otu_num <- length(otu_id)

for (i in 2:ncol(flower_dat)) {
otu_id <- unique(flower_dat[,i])
otu_id <- otu_id[otu_id != '']
core_otu_id <- intersect(core_otu_id, otu_id)
otu_num <- c(otu_num, length(otu_id))
}
core_num <- length(core_otu_id)

#下文中绘制椭圆的draw.ellipse()、draw.circle()等命令,需要plotrix包实现
library(plotrix)

#定义备选颜色(示例数据20个样本,所以我设置了20种颜色)
ellipse_col <- c('#6181BD4E','#F348004E','#64A10E4E','#9300264E','#464E044E','#049a0b4E','#4E0C664E','#D000004E','#FF6C004E','#FF00FF4E','#c7475b4E','#00F5FF4E','#BDA5004E','#A5CFED4E','#f0301c4E','#2B8BC34E','#FDA1004E','#54adf54E','#CDD7E24E','#9295C14E')

#构建作图函数(参考自大神博客 https://www.cnblogs.com/xudongliang/p/7884667.html)
flower_plot <- function(sample, otu_num, core_otu, start, a, b, r, ellipse_col, circle_col) {
par( bty = 'n', ann = F, xaxt = 'n', yaxt = 'n', mar = c(1,1,1,1))
plot(c(0,10),c(0,10),type='n')
n <- length(sample)
deg <- 360 / n
res <- lapply(1:n, function(t){
draw.ellipse(x = 5 + cos((start + deg * (t - 1)) * pi / 180),
y = 5 + sin((start + deg * (t - 1)) * pi / 180),
col = ellipse_col[t],
border = ellipse_col[t],
a = a, b = b, angle = deg * (t - 1))
text(x = 5 + 2.5 * cos((start + deg * (t - 1)) * pi / 180),
y = 5 + 2.5 * sin((start + deg * (t - 1)) * pi / 180),
otu_num[t])

if (deg * (t - 1) < 180 && deg * (t - 1) > 0 ) {
text(x = 5 + 3.3 * cos((start + deg * (t - 1)) * pi / 180),
y = 5 + 3.3 * sin((start + deg * (t - 1)) * pi / 180),
sample[t],
srt = deg * (t - 1) - start,
adj = 1,
cex = 1
)
} else {
text(x = 5 + 3.3 * cos((start + deg * (t - 1)) * pi / 180),
y = 5 + 3.3 * sin((start + deg * (t - 1)) * pi / 180),
sample[t],
srt = deg * (t - 1) + start,
adj = 0,
cex = 1
)
}
})
draw.circle(x = 5, y = 5, r = r, col = circle_col, border = NA)
text(x = 5, y = 5, paste('Core:', core_otu))
}

#调用上述函数作图,视情况修改参数
png('flower.png', width = 1500, height = 1500, res = 200, units = 'px')
flower_plot(sample = sample_id, otu_num = otu_num, core_otu = core_num,
start = 90, a = 0.5, b = 2, r = 1, ellipse_col = ellipse_col, circle_col = 'white')
dev.off()
#注:参数a和b用于设置花瓣椭圆的尺寸,ellipse_col用于设置花瓣椭圆的颜色;参数r用于设置中心圆圈尺寸,circle_col用于设置中心圆圈的颜色

   

    本示例的最终结果“flower.png”如下。共包含20个样本,外圈数值为各样本内所含元素种类总数(注意这里我展示的是元素总数,而不是各样本的特有元素数量),中心圆圈内为共有元素数量。

    怎么样,效果还可以吧。


    最后,扫一扫下方二维码,可关注本公众号“生信小白鱼”,同样谢谢大家支持。




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

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