如何使用R语言igraph包绘制符合特定样式要求的网络图?
R语言igraph绘制网络图的优化实现
需求说明
- 权重为0时不显示对应边;
- 为parameter(灰色边)、feedback(蓝色边)、design(粉色边)、intent(黄色边)四个属性分别创建独立边,两节点间可存在0-4条边;
- 节点标签始终位于节点旁,且不与边或箭头重叠;
- 节点根据所属类别设置不同颜色(如E类为绿色、I类为红色)。
现有代码
#install.packages("igraph") library(igraph) data <- read.csv(file.choose(), sep=";", header=T) y <- data.frame(data$From, data$To, data$Weight, data$Class, data$Parameter, data$Feedback, data$Design, data$Intent) net <- graph.data.frame(y, directed=T) V(net) E(net) V(net)$label <- V(net)$name V(net)$degree <- degree(net) hist(V(net)$degree, col="red", main="Histogram of Node Degree", ylab="Frequency", xlab="Degree of Vertices") set.seed(222) plot(net, edge.width = y$data.Weight, vertex.color="red", vertex.size=5, edge.arrow.size=1, edge.color="blue", vertex.label.dist=1.5, vertex.label.cex=1, vertex.label.color="black")
相关图示
- 当前网络图:![当前网络图,节点均为红色,边为蓝色,标签与边存在重叠]
- 数据集截图:![数据集截图,包含From、To、Weight、Class、Parameter、Feedback、Design、Intent列]
- 目标网络图:![目标网络图示例,节点分颜色显示,不同类型边用不同颜色区分,标签位置合理]
优化后的代码
library(igraph) # 读取数据 data <- read.csv(file.choose(), sep=";", header=T) # 拆分四类边数据,过滤权重为0的情况 edge_types <- list( parameter = data[data$Parameter != 0, c("From", "To", "Parameter")], feedback = data[data$Feedback != 0, c("From", "To", "Feedback")], design = data[data$Design != 0, c("From", "To", "Design")], intent = data[data$Intent != 0, c("From", "To", "Intent")] ) # 构建空的有向图 net <- make_empty_graph(directed = TRUE) # 添加所有节点(去重) all_nodes <- unique(c(data$From, data$To)) net <- add_vertices(net, length(all_nodes), name = all_nodes) # 为每类边添加到图中,并设置属性 for (type in names(edge_types)) { edges <- edge_types[[type]] if (nrow(edges) > 0) { # 获取节点索引 from_idx <- match(edges$From, V(net)$name) to_idx <- match(edges$To, V(net)$name) # 添加边 net <- add_edges(net, c(rbind(from_idx, to_idx))) # 设置边的属性:类型、颜色、权重 edge_attr(net, "type") <- c(edge_attr(net, "type"), rep(type, nrow(edges))) edge_attr(net, "color") <- c(edge_attr(net, "color"), switch(type, parameter = "gray", feedback = "blue", design = "pink", intent = "yellow")) edge_attr(net, "weight") <- c(edge_attr(net, "weight"), edges[[3]]) } } # 设置节点颜色:根据Class列匹配(假设每个节点Class唯一) node_class <- data.frame(name = all_nodes, class = sapply(all_nodes, function(x) { unique(data$Class[data$From == x | data$To == x]) })) V(net)$color <- ifelse(node_class$class == "E", "green", "red") # 设置节点标签属性,减少重叠 V(net)$label <- V(net)$name V(net)$label.dist <- 1.2 V(net)$label.degree <- -pi/4 # 调整标签角度,避免与边重叠 V(net)$label.cex <- 1 V(net)$label.color <- "black" # 基础视觉设置 V(net)$size <- 5 E(net)$width <- E(net)$weight E(net)$arrow.size <- 1 # 绘制网络图(用FR布局优化节点分布) set.seed(222) plot(net, layout = layout_with_fr)
代码实现说明
- 过滤0权重边:针对四类边分别筛选权重非0的行,仅保留需要展示的边;
- 独立边类型创建:拆分四类边数据逐一添加到图中,为每类边绑定对应颜色属性,支持两节点间多条不同类型边共存;
- 标签重叠优化:通过
vertex.label.degree调整标签角度,配合layout_with_fr布局优化节点间距,减少标签与边的重叠; - 节点分类着色:建立节点与Class的映射关系,按类别设置绿色(E类)或红色(I类)节点颜色。
内容的提问来源于stack exchange,提问作者unicus.sapiens
相关产品推荐
相关产品推荐

