本文作者蒋刘一琦,自嘲是一个有艺术追求的生信狗,毕业于浙江大学生物信息学专业,目前在复旦大学就读研究生,研究方向为宏基因组。
在生物信息领域我们常常使用R语言对数据可视化。在对数据可视化的时候,我们需要明确想要展示的信息,从而选择最为合适的图突出该信息。本系列文章将介绍多种基于不同R包的作图方法,希望能够帮助到各位读者。
什么是Edge Bunding图
Edge Bunding图是一种数据可视化的方式,用于展示不同节点之间的联系。与普通的network的差别在于,它使用曲线来展示节点间的连接,而非直线,并会把相同趋势的曲线捆绑在一起,就像整理数据线的“环”。因此在关联较多的情况下,这一类可视化的方式可能更有利于展现趋势的变化,不会显得复杂而混乱。具体我们可以看一下下面的例子:
可以看到上图中,作图是用直线进行连接的,很难了解其中的规律。而使用Edge Bunding图后,将同一趋势的线捆绑在一起后,就会出现较为清晰的规律。因此,这一类型的图很适合展现较为复杂的关联(不过其实Cytoscape等软件中也有类似的功能)。
Edge Bunding图除了环形,还有多种形式,比如下图。当然,在微生物组领域因为存在物种分类的信息,所以可能环形的排布方式能够呈现出更加直观的规律。
Force-Directed Edge Bundling for Graph Visualization
如何作Edge Bunding图
代码来源:https://www.r-graph-gallery.com/310-custom-hierarchical-edge-bundling.html (感觉原网站就做的挺好看,所以主要会讲解一下所需要的数据)
1)需要什么样的数据 本次的绘制我们使用igraph和ggraph包。其实igraph包本身就是一个专门用于绘制网络图的R包(igraph也有对应的python和C包),而ggraph是一个基于ggplot2的包,它可以让网络图变得更加“优雅”(我最近学会的新形容词)。
那么,具体我们需要什么数据呢? 其实,基本上,构建各种网络图所需要的数据无外乎:起始节点(from)、终止节点(to)和连线属性(比如相关性的强度等)。那么,我们首先来构建一组数据:
代码语言:javascript复制library(ggraph)
library(igraph)
library(tidyverse)
set.seed(617)
d1 <- data.frame(from="origin", to=paste("group", seq(1,10), sep=""))
d2 <- data.frame(from=rep(d1$to, each=10), to=paste("subgroup", seq(1,100), sep="_"))
hierarchy <- rbind(d1, d2)
#构建连接
all_leaves <- paste("subgroup", seq(1,100), sep="_")
connect <- rbind(
data.frame( from=sample(all_leaves, 100, replace=T) , to=sample(all_leaves, 100, replace=T)),
data.frame( from=sample(head(all_leaves), 30, replace=T) , to=sample( tail(all_leaves), 30, replace=T)),
data.frame( from=sample(all_leaves[25:30], 30, replace=T) , to=sample( all_leaves[55:60], 30, replace=T)),
data.frame( from=sample(all_leaves[75:80], 30, replace=T) , to=sample( all_leaves[55:60], 30, replace=T)) )
#随机生成0~1之间的关联强度
connect$value <- runif(nrow(connect))
vertices <- data.frame(
name = unique(c(as.character(hierarchy$from), as.character(hierarchy$to))) ,
value = runif(111)
)
vertices$group <- hierarchy$from[ match( vertices$name, hierarchy$to ) ]
vertices$group <- factor(vertices$group,levels=unique(vertices$group))
head(hierarchy)
from to
1 origin group1
2 origin group2
3 origin group3
4 origin group4
5 origin group5
6 origin group6
head(vertices)
name value group
1 origin 0.3141327 <NA>
2 group1 0.7896345 origin
3 group2 0.3868480 origin
4 group3 0.8608597 origin
5 group4 0.8597895 origin
6 group5 0.5379710 origin
mygraph <- graph_from_data_frame( hierarchy, vertices=vertices )#this function from igraph package
#选取connect中有的节点
from <- match( connect$from, vertices$name)
to <- match( connect$to, vertices$name)
2)如何作图
代码语言:javascript复制library(RColorBrewer)
#plot
p<-ggraph(mygraph, layout = 'dendrogram', circular = TRUE)
geom_node_point(aes(filter = leaf, x = x*1.05, y=y*1.05,colour=group)) #根据group给节点的颜色
theme_void()
p geom_conn_bundle(data = get_con(from = from, to = to), alpha=0.2, width=0.6, aes(colour=value),tension=1) #alpha线的透明度,width线的宽度,tension是线的“密集”程度
scale_edge_colour_distiller(palette = "RdPu") #设定线的颜色
scale_color_manual(values=colorRampPalette(brewer.pal(8, "Accent"))(10))#设定节点的颜色
Edge Bundling
我们可以来比较一下修改一些设定之后的区别:
参数tension的影响
不同tension值对网络图的影响
参数width的影响
不同width值对网络图的影响
当然其实也可以不用做成circle,比如把ggraph中的layout改为circlepack,即:
代码语言:javascript复制#plot
p<-ggraph(mygraph, layout = 'circlepack', circular =T)
#geom_conn_bundle(data = get_con(from = from, to = to), alpha=0.2, colour="skyblue", tension = .5)
geom_node_point(aes(filter = leaf, x = x*1.05, y=y*1.05,colour=group))
theme_void()
p geom_conn_bundle(data = get_con(from = from, to = to), alpha=0.2, width=1, aes(colour=value),tension=1)
scale_edge_colour_distiller(palette = "RdPu")
scale_color_manual(values=colorRampPalette(brewer.pal(8, "Accent"))(10))
然后就会出现一张神奇的图。
不同的layout方式
今天的分享就到这里啦。
代码语言:javascript复制 编辑:吴盼成