「R」数据可视化21: Edge Bunding图

2020-10-09 15:43:39 浏览数 (1)

本文作者蒋刘一琦,自嘲是一个有艺术追求的生信狗,毕业于浙江大学生物信息学专业,目前在复旦大学就读研究生,研究方向为宏基因组。

在生物信息领域我们常常使用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复制
                                  编辑:吴盼成

0 人点赞