前言:
而今咱们对“用igraph做network图”大体比较关注,朋友们都想要学习一些“用igraph做network图”的相关知识。那么小编同时在网上收集了一些对于“用igraph做network图””的相关内容,希望兄弟们能喜欢,你们快快来了解一下吧!前言
在前面几节,我们对 igraph 进行了一些简单介绍。接下来我们要介绍的是 ggraph 包的使用
通常,ggraph 会和 tidygraph 一起搭配使用,这两个包都是 Thomas Lin Pedersen 写的。
tidygraph 提供了一系列 tidy API 用于操作图,通常可以将图对象设计为两个 tidy 表,一个用于表示 node 数据,另一个用于表示 edge 数据。还提供了一些额外的动词用于操作这两个表,同时也提供了很多的图论算法,让图形对象的处理看起来更像是在处理数据框。
ggraph 是 ggplot2 的扩展,用于绘制关系型数据结构,如网络、图和树等。ggraph 包含 3 个核心概念:
layout:定义图的布局,包含所有的 igraph 布局以及额外的一些布局,如蜂巢图、圆堆积图等nodes:定义节点图形属性,使用 geom_node_*() 函数来控制edges:定义边的图形属性,使用 geom_edge_*() 函数来控制
两个包搭配使用,可以让网络对象的处理与绘制,和我们绘制数据框结构更相似,以 ggplot2 的方式来绘制网络对象
安装导入
install.packages('ggraph')install.packages('tidygraph')# 开发版devtools::install_github('thomasp85/ggraph')devtools::install_github('thomasp85/tidygraph')library(ggraph)library(tidygraph)创建图
我们还是以 KEGG 的通路作为示例,这次我们找的是 p53 signaling pathway,网络结构的获取方式见前两节的代码
我们使用 tbl_graph() 函数来创建 tbl_graph 对象
edges <- read.csv('~/Downloads/p53_signaling_pathway.csv')colnames(edges) <- c("from", "to")nodes <- data.frame(name = unique(union(edges$from, edges$to)))g <- tbl_graph(nodes = nodes, edges = edges)
查看对象类型
> class(g)[1] "tbl_graph" "igraph"
tbl_graph 对象本质上是一个 igraph 对象,可以看到 tbl_graph() 函数与 graph_from_data_frame() 函数的参数是很像的
也可以用 igraph 图对象来创建 tbl_graph 对象
library(igraph)ig <- graph_from_data_frame(d = edges, vertices = nodes)ig_tidy <- as_tbl_graph(ig)
查看这三个对象的类型
> class(g)[1] "tbl_graph" "igraph" > class(ig)[1] "igraph"> class(ig_tidy)[1] "tbl_graph" "igraph">> is.tbl_graph(g)[1] TRUE> is.tbl_graph(ig)[1] FALSE> is.tbl_graph(ig_tidy)[1] TRUE
查看 tbl_graph 对象
> g# A tbl_graph: 61 nodes and 68 edges## A directed acyclic simple graph with 1 component## Node Data: 61 x 1 (active) name <chr> 1 MDM4 2 CHEK1 3 ATR 4 CHEK2 5 ATM 6 IGFBP3# … with 55 more rows## Edge Data: 68 x 2 from to <int> <int>1 1 222 1 153 2 15# … with 65 more rows
as_tbl_graph() 函数还可以将很多其他类型的数据转换为 tbl_graph 对象,例如 hclust 对象、邻接矩阵、dendrogram 对象等等
tidygraph 也提供了很多简便函数,create_*() 函数用于创建一些常见的图结构
par(mfrow= c(1, 3))plot(create_star(10))plot(create_ring(10))plot(create_tree(n = 20, children = 3), edge.arrow.size = .4)
play_*() 函数用于创建模拟图
par(mfrow= c(1, 3))plot(play_geometry(6, 1, torus = FALSE))plot(play_islands(4, 10, 0.7, 3))plot(play_forestfire(20, 0.5), edge.arrow.size = .2)
可以使用 igraph 的绘制方式来调整和绘制 tbl_graph 图对象
布局
使用 ggraph 来绘制图形
ggraph(g) + geom_edge_link() + geom_node_point() + theme_graph()
ggraph() 函数相当于 ggplot2::ggplot(),根据传入的图对象以及布局来创建绘图对象
ggraph 默认会根据图结构自动推断布局,也可以使用指定 layout 参数的值
ggraph(g, layout = 'kk') + geom_edge_link() + geom_node_point() + theme_graph()
如果布局算法可以接受额外的参数,也可以在 ggraph() 函数中一并指定
ggraph(g, layout = 'kk', maxiter = 100) + geom_edge_link() + geom_node_point() + theme_graph()
或者用 create_layout() 函数来创建布局,它接受的参数与 ggraph() 一样,但是返回的是 layout_ggraph 对象,可以在后续的图结构中使用。例如
layout <- create_layout(g, layout = 'eigen')ggraph(layout) + geom_edge_link() + geom_node_point() + theme_graph()
我们可以看到,返回的对象是包含节点位置及属性信息的数据框
> head(layout) x y circular name .ggraph.orig_index .ggraph.index1 -0.04065655 0.05622353 FALSE MDM4 1 12 -0.01929743 0.04913762 FALSE CHEK1 2 23 -0.01929743 0.04913762 FALSE ATR 3 34 -0.01929743 0.04913762 FALSE CHEK2 4 45 -0.01929743 0.04913762 FALSE ATM 5 56 0.50281399 0.07229403 FALSE IGFBP3 6 6
查看对象的所有属性
> attributes(layout)$names[1] "x" "y" "circular" "name" ".ggraph.orig_index"[6] ".ggraph.index" $row.names [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39[40] 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61$class[1] "layout_tbl_graph" "layout_ggraph" "data.frame" $graph# A tbl_graph: 61 nodes and 68 edges## A directed acyclic simple graph with 1 component## Node Data: 61 x 2 (active) name .ggraph.orig_index <chr> <int>1 MDM4 12 CHEK1 23 ATR 34 CHEK2 45 ATM 56 IGFBP3 6# … with 55 more rows## Edge Data: 68 x 2 from to <int> <int>1 1 222 1 153 2 15# … with 65 more rows$circular[1] FALSE
ggraph 包提供了许多不同的布局,包括 igraph 所有的布局,同时也提供了一些它自己设计的布局,有超过 20 种布局可供选择。
通常来说,不同的布局算法对图的展示差异很大,因此,为自己的数据找到一个合适的布局很重要。
也可以自己设计一个布局函数,接受一个 tbl_graph 对象,并返回一个位置数据框。或者直接提供一个位置矩阵或数据框作为布局
1. 圆形布局
一些布局既可以显示在笛卡尔坐标系中,也可以在极坐标中有效地进行展示。对于 ggplot2 来说,可以使用 coord_polar() 转换为极坐标轴。但这并不适用于 ggraph,我们通过 circular 参数将布局转换为径向表示。
我们先为边添加一列信息,用于表示基因之间的表达值的相关性,-1 表示负相关,1 为正相关,0 为不相关
edges <- edges %>% mutate(corr = sample(-1:1, size = n(), replace = TRUE)) g <- tbl_graph(nodes = nodes, edges = edges)linear 布局
对于线性布局,即将所有基因放置在一条直线上,然后使用 geom_edge_arc 将边绘制成弧形
ggraph(g, layout = 'linear') + geom_edge_arc(aes(colour = factor(corr))) + geom_node_point() + theme_graph()
设置 circular = TRUE,转换为径向表示
ggraph(g, layout = 'linear', circular = TRUE) + geom_edge_arc(aes(colour = factor(corr))) + geom_node_point() + coord_fixed() + theme_graph()partition 布局
分区布局是一种显示分层结构的方式,每一层都会对前一层的切片进行分割。
例如,我们将节点的形状设置为条块 geom_node_tile
graph <- tbl_graph(flare$vertices, flare$edges)ggraph(graph, 'partition') + geom_node_tile(aes(fill = depth), size = 0.25) + theme_graph()
分区布局的圆形表示,注意节点的形状变成了圆弧条形 geom_node_arc_bar
ggraph(graph, 'partition', circular = TRUE) + geom_node_arc_bar(aes(fill = depth), size = 0.25) + coord_fixed() + theme_graph()
并不是所有的布局都支持圆形表示,下面的布局将会忽略 circular 参数
2. node — edge 布局
我们可以直接使用 igraph 中定义的布局算法,例如
lay <- c('stress', 'fr', 'lgl', 'graphopt')plot_fun <- function(g, layout) { p <- ggraph(g, layout = layout) + geom_edge_link(aes(colour = factor(corr)), show.legend = FALSE) + geom_node_point() + labs(caption = paste0('Layout: ', layout)) + theme_graph() return(p)}grid.newpage()pushViewport(viewport(layout = grid.layout(2, 2)))for (i in seq_along(lay)) { x = (i - 1) %/% 2 + 1 y = (i - 1) %% 2 + 1 p = plot_fun(g, lay[i]) print(p, vp = viewport(layout.pos.row = x, layout.pos.col = y))}3. 蜂巢图
蜂巢图也是一种 node-edge 图,它使用的是节点的信息,将节点进行分类
g <- g %>% mutate(friends = ifelse( centrality_degree(mode = 'all') < 3, "few", ifelse(centrality_degree(mode = 'all') > 3, "many", "medium") ))ggraph(g, 'hive', axis = friends) + geom_edge_hive(aes(colour = factor(corr))) + geom_axis_hive(aes(colour = friends), size = 2, label = FALSE) + coord_fixed() + theme_graph()4. 焦点布局
将焦点聚集在一个或一组节点上,其他节点则相对于该位置放置
ggraph(g, 'focus', focus = node_is_center()) + ggforce::geom_circle(aes(x0 = 0, y0 = 0, r = r), data.frame(r = 1:5), colour = 'grey') + geom_edge_link(aes(colour = factor(corr)), show.legend = FALSE) + geom_node_point() + coord_fixed() + theme_graph()5. 层次布局圆堆积图:以包含的方式来展示层次结构
graph <- tbl_graph(flare$vertices, flare$edges)ggraph(graph, 'circlepack', weight = size) + geom_node_circle(aes(fill = factor(depth)), size = 0.25, n = 50) + coord_fixed() + theme_graph()堆积树状图
ggraph(graph, 'circlepack', weight = size) + geom_edge_link() + geom_node_point(aes(colour = factor(depth))) + coord_fixed() + theme_graph()树状图
矩形层次关系
ggraph(graph, 'treemap', weight = size) + geom_node_tile(aes(fill = factor(depth)), size = 0.25) + theme_graph()
ggraph(graph, 'treemap', weight = size) + geom_edge_link() + geom_node_point(aes(colour = factor(depth))) + theme_graph()
根据树的不同深度进行绘制
ggraph(graph, 'tree') + geom_edge_diagonal() + theme_graph()
层次聚类树状图
dendrogram <- hclust(dist(iris[, 1:4]))ggraph(dendrogram, 'dendrogram', height = height) + geom_edge_elbow() + theme_graph()
圆形树状图
ggraph(dendrogram, 'dendrogram', circular = TRUE) + geom_edge_elbow() + coord_fixed() + theme_graph()
系统发育树,不存在根节点,使用无根布局
tree <- create_tree(100, 2, directed = FALSE) %>% activate(edges) %>% mutate(length = runif(n()))ggraph(tree, 'unrooted', length = length) + geom_edge_link() + theme_graph()6. 矩阵布局
矩阵布局是将节点放置在对角线,如果对应位置的两个节点之间有交叠,那矩阵中对应的行列将会绘制一个点或矩形。
graph <- create_notable('zachary')ggraph(graph, 'matrix', sort.by = node_rank_leafsort()) + geom_edge_point(mirror = TRUE) + coord_fixed() + theme_graph()
不同的节点顺序,会影响矩阵布局的形状
ggraph(graph, 'matrix', sort.by = node_rank_spectral()) + geom_edge_point(mirror = TRUE) + coord_fixed() + theme_graph()7. Fabric 布局
Fabric 布局是一种可扩展的特殊的 BioFabric 布局。其特殊的地方在于,它将节点表示为水平线,边表示为连接两个水平线的竖直线
ggraph(g, 'fabric', sort.by = node_rank_fabric()) + geom_node_range(colour = 'grey') + geom_edge_span(end_shape = 'square') + coord_fixed() + theme_graph()
添加一份重复的阴影边
ggraph(g, 'fabric', sort.by = node_rank_fabric(), shadow.edges =TRUE) + geom_node_range(colour = 'grey') + geom_edge_span(aes(filter = shadow_edge), colour ='lightblue' , end_shape = 'square') + geom_edge_span(aes(filter = !shadow_edge), end_shape = 'square') + coord_fixed() + theme_graph()
标签: #用igraph做network图