You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggraph中固定节点位置以生成可对比的多样网络?

固定节点位置的对比网络图谱实现方案

需求说明

需要生成多幅以指定节点为中心的网络图谱,满足以下要求:

  • 所有节点(含中心节点)的位置固定,便于不同网络间直观对比
  • 当前网络未涉及的节点显示为灰色(半透明)状态
  • 节点按固定顺序环绕中心节点排列

实现步骤

  • 预定义全局节点集合:先提取所有唯一节点并按固定顺序排序,确保所有图谱的节点基础集合一致
  • 生成固定布局:针对每个中心节点,预先生成圆形focus布局并保存坐标,保证不同图谱的节点位置完全匹配
  • 节点状态标记:在节点数据中添加标记,区分当前网络包含的节点和未涉及节点,未涉及节点设置为灰色半透明
  • 边数据过滤:仅保留与当前中心节点相关的边,无关边不渲染
  • 统一视觉样式:统一节点大小、标签样式、边的配色和宽度,保证多图对比的一致性

修改后的完整代码

library(tidyverse)
library(ggraph)
library(tidygraph)

set.seed(1234)

# 原始边数据
links_all = tibble::tribble(
  ~x,  ~input,    ~output,   ~direction,  ~weight,  
  2,   "Group3",  "Group4",  "positive",  0.55076, 
  3,   "Group3",  "Group5",  "positive",  0.25263, 
  4,   "Group3",  "Group7",  "positive",  0.14137, 
  5,   "Group3",  "Group8",  "positive",  0.1532,  
  6,   "Group3",  "Group6",  "positive",  0.51479, 
  7,   "Group3",  "Group9",  "positive",  0.2315,  
  8,   "Group3",  "Group1",  "positive",  0.21106, 
  9,   "Group3",  "Group2",  "negative",  0.51237, 
  12,  "Group4",  "Group5",  "positive",  0.14874, 
  13,  "Group4",  "Group7",  "positive",  0.16683, 
  14,  "Group4",  "Group8",  "positive",  0.235,   
  15,  "Group4",  "Group6",  "positive",  0.43237, 
  16,  "Group4",  "Group9",  "positive",  0.30848, 
  17,  "Group4",  "Group1",  "positive",  0.0544,  
  18,  "Group4",  "Group2",  "negative",  0.48404, 
  22,  "Group5",  "Group7",  "positive",  0.22572, 
  24,  "Group5",  "Group6",  "positive",  0.1611,  
  25,  "Group5",  "Group9",  "positive",  0.09827, 
  26,  "Group5",  "Group1",  "positive",  0.15555, 
  27,  "Group5",  "Group2",  "negative",  0.27293, 
  32,  "Group7",  "Group8",  "positive",  0.0736,  
  33,  "Group7",  "Group6",  "positive",  0.12604, 
  34,  "Group7",  "Group9",  "positive",  0.13935, 
  35,  "Group7",  "Group1",  "negative",  0.0994,  
  42,  "Group8",  "Group6",  "positive",  0.08693, 
  43,  "Group8",  "Group9",  "positive",  0.23976, 
  44,  "Group8",  "Group1",  "negative",  0.42419, 
  45,  "Group8",  "Group2",  "negative",  0.27792, 
  52,  "Group6",  "Group9",  "positive",  0.1356,  
  53,  "Group6",  "Group1",  "positive",  0.14775, 
  54,  "Group6",  "Group2",  "negative",  0.33881, 
  62,  "Group9",  "Group1",  "negative",  0.07413, 
  63,  "Group9",  "Group2",  "negative",  0.2427,  
  72,  "Group1",  "Group2",  "negative",  0.56563
)

# 提取所有唯一节点,按固定顺序排序
all_nodes = links_all %>%
  select(input, output) %>%
  pivot_longer(everything(), values_to = "id") %>%
  distinct(id) %>%
  arrange(id) %>%
  pull(id)

# 预生成所有中心节点的固定布局
get_fixed_layout = function(center_group) {
  # 创建包含所有节点的临时图
  temp_nodes = tibble(id = all_nodes)
  temp_edges = links_all %>%
    filter(input == center_group | output == center_group) %>%
    rename(from = input, to = output) %>%
    select(from, to, direction, weight)
  
  temp_graph = tbl_graph(nodes = temp_nodes, edges = temp_edges, directed = FALSE)
  
  # 生成focus布局,固定中心为目标节点,圆形排列
  layout = create_layout(temp_graph, layout = "focus", focus = which(temp_nodes$id == center_group), circular = TRUE)
  
  # 保存布局坐标,确保顺序与all_nodes一致
  layout %>%
    arrange(match(id, all_nodes)) %>%
    select(x, y, id)
}

# 生成对比用图谱函数
plot_compare_graph = function(current_group) {
  # 获取固定布局
  fixed_layout = get_fixed_layout(current_group)
  
  # 筛选当前组的边数据
  current_edges = links_all %>%
    rename(from = input, to = output) %>%
    filter(from == current_group | to == current_group) %>%
    mutate(weight_class = as.character(round(weight, 1)))
  
  # 标记节点是否在当前网络中
  node_data = fixed_layout %>%
    mutate(in_network = id %in% c(current_edges$from, current_edges$to))
  
  # 设置边宽度映射
  weight_levels = unique(current_edges$weight_class)
  width_values = as.numeric(weight_levels) * 5
  names(width_values) = weight_levels
  
  # 绘图
  set_graph_style()
  
  ggraph(node_data, layout = "manual", x = x, y = y) +
    # 绘制边(仅当前组相关)
    geom_edge_arc(data = current_edges, aes(x = x, y = y, xend = xend, yend = yend, color = direction, width = weight_class),
                  inherit.aes = FALSE) +
    # 绘制节点:当前网络节点用彩色,未涉及用灰色半透明
    geom_node_point(aes(size = 2, color = ifelse(in_network, id, "uninvolved"), alpha = in_network)) +
    # 节点标签
    geom_node_label(aes(label = id),
                    size = 2,
                    nudge_x = 0.1,
                    nudge_y = 0.1,
                    label.padding = unit(0.25, "lines"),
                    label.r = unit(0.15, "lines"),
                    label.size = 0.25,
                    family = "sans") +
    # 样式配置
    scale_edge_color_manual(values = c("negative" = "#ab0033", "positive" = "#009d4f")) +
    scale_edge_width_manual(values = width_values) +
    scale_color_manual(values = c("uninvolved" = "#cccccc", setNames(scales::hue_pal()(length(all_nodes)), all_nodes))) +
    scale_alpha_manual(values = c(TRUE = 1, FALSE = 0.5)) +
    guides(alpha = "none", color = guide_legend(title = "Groups")) +
    labs(title = paste("Centered on", current_group))
}

# 生成对比图谱
Group1_plot = plot_compare_graph("Group1")
Group1_plot

Group7_plot = plot_compare_graph("Group7")
Group7_plot

内容的提问来源于stack exchange,提问作者cdjemiel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:25:48