R语言如何绘制相互作用网络图

前言

本篇是使用R语言的ggraph系列的包绘制各种网络图的教程。

什么是相互作用网络图

三要素:结点连线布局

在相互作用网络图中,结点通常代表个体或实体,连线则表示它们之间的相互作用或联系,布局则是这些点和线通过什么方式去排布。

以上就是三种不同的排布方式例子。

绘图前的数据准备

结点数据

第一列是结点的唯一ID,必不可少。还可以有其他映射,例如示例数据中提供了结点的文字标记,结点大小和结点分组,可以通过后面这些列的数据定义结点的颜色大小等。

demo数据可以在这下载:https://www.r2omics.cn/res/demodata/network/node.txt

# A tibble: 50 x 4
      id label    size group
   <int> <chr>   <int> <chr>
 1     1 Node 1     24 node2
 2     2 Node 2     28 node2
 3     3 Node 3     23 node3
 4     4 Node 4     12 node2
 5     5 Node 5     19 node2
 6     6 Node 6     27 node3
 7     7 Node 7     20 node3
 8     8 Node 8     14 node1
 9     9 Node 9     29 node2
10    10 Node 10    23 node2
# i 40 more rows

连线数据

前两列定义连线,从哪个节点到哪个节点,里面的内容正是结点数据中的结点ID。同样可以有其他映射,定义连线的粗细颜色分组等。

demo数据可以在这下载:https://www.r2omics.cn/res/demodata/network/link.txt

# A tibble: 150 x 4
    from    to group width
   <int> <int> <chr> <int>
 1    46     8 link2     2
 2    35    25 link3     3
 3    40    21 link2     1
 4    46    45 link1     1
 5    30    18 link3     3
 6    15    42 link1     2
 7    24    31 link1     4
 8    49     6 link3     5
 9    23     7 link2     3
10    43    41 link1     4
# i 140 more rows

R语言如何绘制相互作用网络图

第一步读取了结点和分组数据。然后对结点的出现顺序排了个序。在圆形布局时,设置文本标记旋转到合适的角度。最后转换为mygraph图形数据格式。

# 代码来源:https://www.r2omics.cn/
# 加载所需包
library(tidyverse)      # 加载 tidyverse 包,提供数据处理和可视化功能
library(ggraph)         # 加载 ggraph 包,用于绘制图形
library(igraph)         # 加载 igraph 包,用于处理图形数据
library(RColorBrewer)   # 加载 RColorBrewer 包,用于设置颜色

# 读取数据
# 结点数据
nodeDf = read.delim("https://www.r2omics.cn/res/demodata/network/node.txt")  # 从网址读取节点数据
# 连线数据
linkDf = read.delim("https://www.r2omics.cn/res/demodata/network/link.txt")  # 从网址读取连线数据

# 排序结点数据
# 默认绘图按照结点中出现的顺序,我们按照结点的分组和大小做了和排序
nodeDf = nodeDf %>%
  arrange(group, size)  # 按照 group 和 size 排序结点数据

# 在圆形布局时,设置文本标记旋转到合适的角度
myCount <- nrow(nodeDf)                    # 获取结点数据行数
nodeDf$id = seq(1, nrow(nodeDf))           # 添加 id 列
angle = 360 * (nodeDf$id - 0.5) / myCount  # 计算角度
nodeDf$hjust <- ifelse(angle > 180, 1.2, -0.2)                     # 根据角度设置水平位置
nodeDf$angle <- ifelse(angle > 180, 90 - angle + 180, 90 - angle)  # 根据角度设置文字角度

# 转换为mygraph图形数据格式
mygraph = graph_from_data_frame(linkDf, vertices = nodeDf, directed = FALSE)  # 将连线数据和结点数据转换为图形数据格式

普通排布

# 使用Fruchterman-Reingold算法布局图
set.seed(123)                     # 设置随机种子
ggraph(mygraph, layout = 'fr') +  # 使用 Fruchterman-Reingold 算法布局
  geom_edge_link(aes(edge_color = group), edge_width = 0.5) +  # 绘制边,根据 group 设置颜色
  geom_node_point(aes(fill = group, size = size), shape = 21, color = 'black', alpha = 0.9) +  # 绘制结点,根据 group 设置填充颜色和 size 大小
  # geom_node_text(aes(label = label), size = 3, repel = FALSE) +  # 添加结点标签
  scale_size_continuous(range = c(2, 5)) +     # 设置结点大小范围
  scale_fill_brewer(palette = "Set1") +        # 设置填充颜色
  scale_edge_color_brewer(palette = "Set1") +  # 设置边的颜色
  theme_void()                                 # 设置图形主题为无背景

还有多种其他排布的算法,star、circle、nicely、grid、sphere、dh、drl、fr、gem、graphopt、kk、lgl、mds

直线排布

ggraph(mygraph, layout = 'linear', circular = FALSE) +        # 使用线性布局,不使用圆形布局
  geom_edge_arc(aes(edge_color = group), edge_width = 0.5) +  # 绘制边,根据 group 设置颜色
  geom_node_point(aes(fill = group, size = size), shape = 21, color = 'black', alpha = 0.9) +  # 绘制结点,根据 group 设置填充颜色和 size 大小
  geom_node_text(aes(label = label), size = 3, repel = FALSE, angle = 90, hjust = 1.2) +       # 添加结点标签,设置标签文字、大小、角度和位置
  scale_size_continuous(range = c(2, 5)) +                    # 设置结点大小范围
  expand_limits(y = c(-1, 0)) +                               # 扩展坐标轴范围
  scale_fill_brewer(palette = "Set1") +                       # 设置填充颜色
  scale_edge_color_brewer(palette = "Set1") +                 # 设置边的颜色
  theme_void()                                                # 设置图形主题为无背景

圆形排布

ggraph(mygraph, layout = 'linear', circular = TRUE) +         # 使用圆形布局
  geom_edge_arc(aes(edge_color = group), edge_width = 0.5) +  # 绘制弧形边,根据 group 设置颜色
  geom_node_point(aes(fill = group, size = size), shape = 21, color = 'black', alpha = 0.9) +  # 绘制结点,根据 group 设置填充颜色和 size 大小
  geom_node_text(aes(label = label, angle = angle, hjust = hjust), size = 3, repel = FALSE) +  # 添加结点标签,设置标签文字、角度和位置
  expand_limits(x = c(-1.3, 1.3), y = c(-1.3, 1.3)) +  # 扩展坐标轴范围
  coord_fixed() +                                      # 设置坐标轴比例相同
  scale_size_continuous(range = c(2, 5)) +             # 设置结点大小范围
  scale_fill_brewer(palette = "Set1") +                # 设置填充颜色
  scale_edge_color_brewer(palette = "Set1") +          # 设置边的颜色
  theme_void()                                         # 设置图形主题为无背景

将geom_edge_arc替换为geom_edge_link,变为直线。

ggraph(mygraph, layout = 'linear', circular = TRUE) +         # 使用圆形布局
  geom_edge_link(aes(edge_color = group), edge_width = 0.5) +  # 绘制弧形边,根据 group 设置颜色
  geom_node_point(aes(fill = group, size = size), shape = 21, color = 'black', alpha = 0.9) +  # 绘制结点,根据 group 设置填充颜色和 size 大小
  geom_node_text(aes(label = label, angle = angle, hjust = hjust), size = 3, repel = FALSE) +  # 添加结点标签,设置标签文字、角度和位置
  expand_limits(x = c(-1.3, 1.3), y = c(-1.3, 1.3)) +  # 扩展坐标轴范围
  coord_fixed() +                                      # 设置坐标轴比例相同
  scale_size_continuous(range = c(2, 5)) +             # 设置结点大小范围
  scale_fill_brewer(palette = "Set1") +                # 设置填充颜色
  scale_edge_color_brewer(palette = "Set1") +          # 设置边的颜色
  theme_void()                                         # 设置图形主题为无背景