r数据可视化分析报告(R数据可视化)
r数据可视化分析报告(R数据可视化)布局函数igraph 中所有布局算法都是 layout_*() 形式,每个布局算法都会返回一个 layout 实例,类似列表型的对象,包含了每个节点在图中的 x、y 坐标。从上面的图可以看出,第一个随机布局,完全看不出什么有价值的信息,而从第二和第三幅可以看出存在某些对称性布局算法用于寻找合适的排列方式,但是找到优秀的排列确实不容易,因此,大部分的算法都是通过间接测量来评估布局的好坏。而且是一种启发式的方法来求解,所以并不是每次都能找到最优解。大部分的布局算法只适用于较小的图,较大的图需要一些特殊技术来处理。
前言图是一种抽象的数学结构,不同对象之间通过线条连接起来,而对象在图中并没有固定的位置表示,不同的放置位置显示出的效果通常是不一样的。
选择一种优秀的布局方式,可以让图形呈现出更好的效果,而 igraph 的工作方式是通过一类 node-edge 的算法来进行布局的。
算法会将节点作为二维或三维空间上的点,使用直线或曲线来连接两个相邻的节点。对于有向图来说,带箭头的线表示连接方向。在边两端的节点可以由不同的几何图形来表示,而一些重要的节点或边的属性可以用来设置图形参数值。
图的可视化通常由三个步骤组成:
- 找到节点在二维或三维空间上合适的排列方式,这一步可能是最重要的。好的布局往往能够解释一些有趣的现象,如对称性、密集连接区域。
从上面的图可以看出,第一个随机布局,完全看不出什么有价值的信息,而从第二和第三幅可以看出存在某些对称性
- 将节点和边的重要属性映射到图像上
- 安排好节点与边的绘制顺序
布局算法用于寻找合适的排列方式,但是找到优秀的排列确实不容易,因此,大部分的算法都是通过间接测量来评估布局的好坏。而且是一种启发式的方法来求解,所以并不是每次都能找到最优解。
大部分的布局算法只适用于较小的图,较大的图需要一些特殊技术来处理。
igraph 中所有布局算法都是 layout_*() 形式,每个布局算法都会返回一个 layout 实例,类似列表型的对象,包含了每个节点在图中的 x、y 坐标。
布局函数
布局是通过 plot() 函数的 layout 参数来控制的,例如
我们随机生成一张图
g<-sample_gnm(n=15 m=25)
plot(g)
随机布局
plot(g layout=layout_randomly)
圆形布局
plot(g layout=layout_in_circle)
力导向布局,最常用的是 Fruchterman-Reingold 算法
plot(g layout=layout_with_fr)
另一种比较常用的力导向算法 Kamada Kawai
plot(g layout=layout_with_kk)
设置树状图
par(mfrow=c(1 3))
tree<-make_tree(20 3)
plot(tree layout=layout_as_tree)
#自底向上
plot(tree layout=layout_as_tree(tree flip.y=FALSE))
#圆形排列
plot(tree layout=layout_as_tree(tree circular=TRUE))
设置根节点
par(mfrow=c(1 2))
tree2<-make_tree(10 3) make_tree(10 2)
plot(tree2 layout=layout_as_tree)
plot(tree2 layout=
layout_as_tree(
tree2 root=c(1 11)
rootlevel=c(2 1)
)
)
传递位置矩阵
g<-sample_gnm(n=15 m=25)
l<-cbind(1:vcount(g) c(1 vcount(g):2))
plot(g layout=l)
我们在前面的介绍中,都只用了 plot() 函数来绘制图形,所有的一切图形属性都是默认的,默认的颜色、大小、布局等。在我们设置了边和节点的颜色属性之后,图片才显示出了不同的颜色。
在这里,我们将介绍如何来调整节点和边的图形属性,igraph 的绘制参数包括
我们以 KEEE 数据库中的 ErbB 信号通路中的 EGF-ERBB2-RAS-ERK 信号通路为例。
利用 KEGG 官网提供的 API 接口,处理并获取通路的图结构,然后将其转换为基因 symbol 边列表,代码如下
library(rvest)
library(tidyverse)
#解析ErbBsignalingpathway网络结构
kmgl<-read_html('http://rest.kegg.jp/get/hsa04012/kgml')
#获取所有基因的entryid
node<-kmgl%>%html_elements(xpath='//entry[@type="gene"]')%>%
html_attrs()%>%
lapply(function(x)c(x['id'] x['name']))%>%
do.call(rbind .)%>%
as.data.frame()
#获取所有entry之间的互作关系
edge<-kmgl%>%html_elements(xpath='//relation')%>%
html_attrs()%>%
lapply(function(x)c(x['entry1'] x['entry2']))%>%
do.call(rbind .)%>%
as.data.frame()
#将entryid转换为KEGGgeneID
net<-inner_join(node edge by=c('id'='entry1'))%>%
inner_join(node by=c('entry2'='id'))%>%
dplyr::select(name.x name.y)%>%
dplyr::rename(source=name.x target=name.y)
#将多对一转换为多个一对一
edges_list<-list()
for(iinseq_along(net[ 1])){
gids<-str_split(gsub("hsa:" '' net[i ]) '')
s<-data.frame('source'=gids[[1]])
t<-data.frame('target'=gids[[2]])
edges_list[[i]]<-crossing(s t)
}
#合并为边列表
all_edges<-do.call(rbind edges_list)
#EGF-ERBB2-RAS-ERKsignalingpathwaygenes
sub_path<-c(
1950 2064 1956 2885
6654 6655 3265 3845
4893 369 673 5894 5604
5605 5594 5595
)
path_id<-all_edges%>%
filter(source%in%sub_path&target%in%sub_path)
#将ENTREZID转换为SYMBOL
library(org.Hs.eg.db)
s<-select(org.Hs.eg.db keys=path_id$source columns='SYMBOL' 'ENTREZID')
t<-select(org.Hs.eg.db keys=path_id$target columns='SYMBOL' 'ENTREZID')
#获取最终的SYMBOL边结构
sub_path<-tibble(
source=s$SYMBOL
target=t$SYMBOL
)%>%
distinct()
#设置基因的类型,是否癌基因或抑癌基因
genes<-unique(union(sub_path$source sub_path$target))
gtype<-rep("other" length(genes))
gtype[grep("(RAS)|(RAF)" genes)]<-"proto-oncogene"
gene_type<-data.frame(
genes=genes
type=gtype
)
#获取突变信息
mut<-read_delim('~/Downloads/luad_broad/data_mutations_mskcc.txt' delim='\t')%>%
dplyr::select(Hugo_Symbol Variant_Classification)%>%
filter(Hugo_Symbol%in%genes)
#每个基因的突变频数,即突变类型
mut_cnt<-group_by(mut Hugo_Symbol)%>%
summarise(mut_count=n())
mut_info<-distinct(mut)%>%
group_by(Hugo_Symbol)%>%
summarise(mut_class=n())%>%
left_join(mut_cnt)
#将基因的所有信息整合在一起
node_attr<-left_join(gene_type mut_info by=c("genes"="Hugo_Symbol"))%>%
replace_na(list(mut_class=0 mut_count=0))
获取代码:https://github.com/dxsbiocc/learn/blob/main/R/data_process/get_hsa04012_kgml.R
突变数据:https://github.com/dxsbiocc/learn/blob/main/data/mutation/data_mutations_mskcc.txt
为了方便,我们并没有考虑通路中基因或蛋白复合物的情况。
创建图
g<-graph_from_data_frame(d=sub_path vertices=node_attr)
plot(g layout=layout_with_fr)
有两种方法来设置节点和边的图形属性,第一种就是在 plot() 函数中传递对应的参数
例如,设置边的箭头大小和曲率
plot(g layout=layout_as_tree
edge.arrow.size=.4
edge.curved=.1
)
plot(g layout=layout.circle
edge.arrow.size=.2
edge.color="#1f78b4"
vertex.color="#33a02c"
vertex.frame.color="#fb9a99"
vertex.label.color="#ff7f00"
)
第二种方法,将图形属性添加到 igraph 对象中。
例如,我们想根据基因的类型设置不同的颜色,根据基因突变频率设置节点的大小
#设置基因的颜色
V(g)$color<-if_else(V(g)$type=="other" "#80b1d3" "#fb8072")
#设置基因的大小
V(g)$size<-log10(V(g)$mut_count 1)*10
#不显示基因名
V(g)$label<-NA
#假设我们有基因之间的相关性,用于设置边的宽度
E(g)$width<-abs(rnorm(n=ecount(g)))
#设置箭头大小和边的颜色
E(g)$arrow.size<-.2
E(g)$edge.color<-"gray80"
#设置布局
graph_attr(g "layout")<-layout_with_lgl
plot(g)
可以在 plot 中覆盖图形属性参数的值
plot(g edge.color="orange" vertex.color="gray50")
添加图例
legend(x=-1.5 y=-1.1 c("other" "proto-oncogene") pch=21
col="#777777" pt.bg=c("#80b1d3" "#fb8072")
pt.cex=2 cex=.8 bty="n" ncol=1)
我们可以只显示节点的文本,而不添加形状
plot(g vertex.shape="none"
vertex.label.font=2
vertex.label.color="gray40"
vertex.label.cex=.7
edge.color="gray85"
edge.arrow.size=.2
)
为基因之间的调控与被调控关系设置不同的颜色
graph_attr(g "layout")<-layout_with_lgl
V(g)$color<-if_else(V(g)$type=="other" "#80b1d3" "#fb8072")
edge.start<-ends(g es=E(g) names=F)[ 1]
edge.col<-V(g)$color[edge.start]
plot(g edge.color=edge.col edge.curved=.1 edge.arrow.size=.3)
根据基因的度来设置基因的大小
deg<-degree(g mode="all")
V(g)$size<-deg*6
plot(g edge.color=edge.col
edge.curved=.1 edge.arrow.size=.3)
大家可以根据需求自己设置不同的颜色属性,就不再一一列举了