R 数据可视化——igraph 布局与绘图
connygpt 2024-11-18 10:41 6 浏览
前言
图是一种抽象的数学结构,不同对象之间通过线条连接起来,而对象在图中并没有固定的位置表示,不同的放置位置显示出的效果通常是不一样的。
选择一种优秀的布局方式,可以让图形呈现出更好的效果,而 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)
# 解析 ErbB signaling pathway 网络结构
kmgl <- read_html('http://rest.kegg.jp/get/hsa04012/kgml')
# 获取所有基因的 entry id
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()
# 将 entry id 转换为 KEGG gene ID
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 (i in seq_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-ERK signaling pathway genes
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)
大家可以根据需求自己设置不同的颜色属性,就不再一一列举了
- 上一篇:ARKit可视化LiDAR点云
- 下一篇:一起学 WebGL:绘制立方体
相关推荐
- 自学Python,写一个挨打的游戏代码来初识While循环
-
自学Python的第11天。旋转~跳跃~,我~闭着眼!学完循环,沐浴着while的光芒,闲来无事和同事一起扯皮,我说:“编程语言好神奇,一个小小的循环,竟然在生活中也可以找到原理和例子”,同事也...
- 常用的 Python 工具与资源,你知道几个?
-
最近几年你会发现,越来越多的人开始学习Python,工欲善其事必先利其器,今天纬软小编就跟大家分享一些常用的Python工具与资源,记得收藏哦!不然下次就找不到我了。1、PycharmPychar...
- 一张思维导图概括Python的基本语法, 一周的学习成果都在里面了
-
一周总结不知不觉已经自学Python一周的时间了,这一周,从认识Python到安装Python,再到基本语法和基本数据类型,对于小白的我来说无比艰辛的,充满坎坷。最主要的是每天学习时间有限。只...
- 三日速成python?打工人,小心钱包,别当韭菜
-
随着人工智能的热度越来越高,许多非计算机专业的同学们也都纷纷投入到学习编程的道路上来。而Python,作为一种相对比较容易上手的语言,也越来越受欢迎。网络上各类网课层出不穷,各式广告令人眼花缭乱。某些...
- Python自动化软件测试怎么学?路线和方法都在这里了
-
Python自动化测试是指使用Python编程语言和相关工具,对软件系统进行自动化测试的过程。学习Python自动化测试需要掌握以下技术:Python编程语言:学习Python自动化测试需要先掌握Py...
- Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能
-
这篇文章不谈江流所专研的营销与运营,而聊一聊技能学习之路,聊一聊Python这门最简单的编程语言该如何学习,我完成的第一个Python项目,将任意公众号的所有历史文章导出成PDF电子书。或许我这个Py...
- 【黑客必会】python学习计划
-
阅读Python文档从Python官方网站上下载并阅读Python最新版本的文档(中文版),这是学习Python的最好方式。对于每个新概念和想法,请尝试运行一些代码片段,并检查生成的输出。这将帮助您更...
- 公布了!2025CDA考试安排
-
CDA数据分析师报考流程数据分析师是指在不同行业中专门从事行业数据搜集、整理、分析依据数据作出行业研究评估的专业人员CDA证书分为1-3级,中英文双证就业面广,含金量高!!?报考条件:满18...
- 一文搞懂全排列、组合、子集问题(经典回溯递归)
-
原创公众号:【bigsai】头条号:程序员bigsai前言Hello,大家好,我是bigsai,longtimenosee!在刷题和面试过程中,我们经常遇到一些排列组合类的问题,而全排列、组合...
- 「西法带你学算法」一次搞定前缀和
-
我花了几天时间,从力扣中精选了五道相同思想的题目,来帮助大家解套,如果觉得文章对你有用,记得点赞分享,让我看到你的认可,有动力继续做下去。467.环绕字符串中唯一的子字符串[1](中等)795.区...
- 平均数的5种方法,你用过几种方法?
-
平均数,看似很简单的东西,其实里面包含着很多学问。今天,分享5种经常会用到的平均数方法。1.算术平均法用到最多的莫过于算术平均法,考试平均分、平均工资等等,都是用到这个。=AVERAGE(B2:B11...
- 【干货收藏】如何最简单、通俗地理解决策树分类算法?
-
决策树(Decisiontree)是基于已知各种情况(特征取值)的基础上,通过构建树型决策结构来进行分析的一种方式,是常用的有监督的分类算法。决策树算法是机器学习中的一种经典算法,它通过一系列的规则...
- 面试必备:回溯算法详解
-
我们刷leetcode的时候,经常会遇到回溯算法类型题目。回溯算法是五大基本算法之一,一般大厂也喜欢问。今天跟大家一起来学习回溯算法的套路,文章如果有不正确的地方,欢迎大家指出哈,感谢感谢~什么是回溯...
- 「机器学习」决策树——ID3、C4.5、CART(非常详细)
-
决策树是一个非常常见并且优秀的机器学习算法,它易于理解、可解释性强,其可作为分类算法,也可用于回归模型。本文将分三篇介绍决策树,第一篇介绍基本树(包括ID3、C4.5、CART),第二篇介绍Ran...
- 大话AI算法: 决策树
-
所谓的决策树算法,通俗的说就是建立一个树形的结构,通过这个结构去一层一层的筛选判断问题是否好坏的算法。比如判断一个西瓜是否好瓜,有20条西瓜的样本提供给你,让你根据这20条(通过机器学习)建立起...
- 一周热门
- 最近发表
- 标签列表
-
- kubectlsetimage (56)
- mysqlinsertoverwrite (53)
- addcolumn (54)
- helmpackage (54)
- varchar最长多少 (61)
- 类型断言 (53)
- protoc安装 (56)
- jdk20安装教程 (60)
- rpm2cpio (52)
- 控制台打印 (63)
- 401unauthorized (51)
- vuexstore (68)
- druiddatasource (60)
- 企业微信开发文档 (51)
- rendertexture (51)
- speedphp (52)
- gitcommit-am (68)
- bashecho (64)
- str_to_date函数 (58)
- yum下载包及依赖到本地 (72)
- jstree中文api文档 (59)
- mvnw文件 (58)
- rancher安装 (63)
- nginx开机自启 (53)
- .netcore教程 (53)