ggnetwork绘图时节点颜色与网络无法同时正常显示求助
问题与解决方案
核心问题
使用ggplot2+ggnetwork绘制带节点颜色编码的网格网络图时,出现矛盾:
- 启用邻接矩阵构建网络,连接显示正常,但节点颜色映射错位
- 注释邻接矩阵代码,颜色显示正确,但无网络连接
原因:当网络包含边时,ggnetwork输出的数据框n包含边记录(行数远大于节点数),直接取前N行的坐标会导致与原始节点的R值对应关系错乱;无网络边时,n仅包含节点记录,对应关系正确。
解决方案
步骤1:将R值作为节点属性加入网络对象
在构建network对象时,直接把R值绑定为节点属性,ggnetwork会自动将该属性带入输出的数据框,避免手动匹配时的错位。
步骤2:正确提取节点数据绘图
绘图时,针对节点和边分别处理:
- 用
geom_edges绘制边(自动识别n中的边记录) - 用
geom_point绘制节点时,通过subset(n, !is.na(vertex.names))筛选出节点行,直接使用内置的R属性映射颜色
通用适配函数
以下函数可适配任意网格(对称/非对称),输入邻接矩阵、节点坐标、R值,直接返回可扩展的ggplot绘图对象:
library(network) library(ggnetwork) library(ggplot2) plot_grid_network <- function(adj_matrix, grid_coords, R_values, edge_color = "grey80", node_size = 3.5, color_low = "steelblue3", color_high = "firebrick3") { # 初始化网络并添加邻接矩阵 gra <- network.initialize(nrow(grid_coords), directed = FALSE) gra <- network.adjacency(adj_matrix, gra) # 将R值作为节点属性加入网络 network::set.vertex.attribute(gra, "R", R_values) # 生成ggnetwork数据框,使用给定坐标布局 n <- ggnetwork(gra, layout = grid_coords, arrow.gap = 0) # 绘图 p <- ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + geom_edges(color = edge_color) + # 节点底层灰色背景 geom_point(data = subset(n, !is.na(vertex.names)), aes(x = x, y = y), size = node_size + 1.5, color = "grey80") + # 节点白色内层 geom_point(data = subset(n, !is.na(vertex.names)), aes(x = x, y = y), size = node_size, color = "white") + # 带颜色映射的节点 geom_point(data = subset(n, !is.na(vertex.names)), aes(color = R), size = node_size) + scale_colour_gradient(low = color_low, high = color_high, name = expression(bold(R)[ix]), limits = range(R_values), na.value = "white") + theme_void() return(p) }
示例验证
对称网格示例
# 对称网格数据 adj_matrix <- matrix(c(0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0), nrow = 9, ncol = 9, byrow = TRUE) grid_coords <- matrix(NA, nrow=3 * 3, ncol=2) cell_size <- 1 origin_x <- 1 origin_y <- 1 k <- 1 for (i in 1:3) { for (j in 1:3) { x <- (j-1) * cell_size + origin_x y <- (i-1) * cell_size + origin_y grid_coords[k,] <- c(x, y) k <- k + 1 } } R <- c(1.0000000, 0.5723928, 0.1447857, 1.4276072, 1.0000000, 0.5723928, 1.8552143, 1.4276072, 1.0000000) # 生成绘图 plot_grid_network(adj_matrix, grid_coords, R)
非对称三角形网格示例
# 非对称三角形网格数据 adj_matrix2 <- matrix(c( 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0), nrow = 10, ncol = 10, byrow = TRUE) Xchords <- c(1,2,3,4,4,4,4,3,2,3) Ychords <- c(1,2,3,4,3,2,1,1,1,2) grid_coords2 <- cbind(Xchords, Ychords) R2 <- c(2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 2.057551, 10.517957 ) # 生成绘图 plot_grid_network(adj_matrix2, grid_coords2, R2)
关键说明
- 函数通过
set.vertex.attribute将R值绑定到网络节点,确保ggnetwork输出的数据框中节点与R值一一对应 - 使用
subset(n, !is.na(vertex.names))精准筛选节点行,避免边记录干扰 - 主题使用
theme_void()替代手动隐藏轴元素,更简洁高效
内容的提问来源于stack exchange,提问作者not.a.hackerman
相关产品推荐
相关产品推荐

