如何使用R/Python/D3JS实现链路在节点合并的桑基/冲积图?
实现方案
完全可以实现该需求,以下为你优先需要的R语言两种实现方案:
方案1:使用networkD3包实现交互式桑基图
networkD3支持自定义节点高度,你只需要显式指定节点的value属性为对应数据集的总大小,即可打破默认的流量守恒逻辑,节点高度会优先匹配你设置的value,链路仅表示匹配关系的数量。
示例代码如下:
library(networkD3) # 1. 定义节点:id从0开始,name为节点名称,value为数据集自身总大小 nodes <- data.frame( id = 0:4, name = c("数据集1", "数据集2", "A(数据集1未匹配)", "B(匹配部分)", "C(数据集2未匹配)"), value = c(200, 150, 125, 75, 75) ) # 2. 定义链路:source、target为节点id,value为链路对应的匹配数量 links <- data.frame( source = c(0, 0, 1, 1), target = c(2, 3, 3, 4), value = c(125, 75, 75, 75) ) # 3. 绘制桑基图,指定nodeWidth调整节点宽度,nodePadding调整节点间距 sankeyNetwork( Links = links, Nodes = nodes, Source = "source", Target = "target", Value = "value", NodeID = "name", nodeValue = "value", # 核心参数:指定节点高度使用节点自身的value值 nodeWidth = 30, nodePadding = 20, fontSize = 12 )
如果你有多步匹配流程,只需要按层级扩展nodes和links数据即可。
方案2:使用ggplot2实现静态冲积图
如果需要输出静态可编辑的图表,可以用ggplot2自定义绘制节点和链路,灵活度更高:
library(ggplot2) library(dplyr) # 模拟节点坐标:x为层级,y为节点底部高度,ymax为节点顶部高度,width为节点宽度 nodes <- data.frame( name = c("数据集1", "数据集2", "A(数据集1未匹配)", "B(匹配部分)", "C(数据集2未匹配)"), x = c(1, 1, 2, 2, 2), y = c(0, 220, 0, 135, 220), ymax = c(200, 370, 125, 210, 295), width = 0.1 ) # 模拟链路坐标,用geom_polygon绘制 flows <- tibble( flow_id = rep(1:4, each = 4), x = c(1.1, 1.9, 1.9, 1.1, 1.1, 1.9, 1.9, 1.1, 1.1, 1.9, 1.9, 1.1, 1.1, 1.9, 1.9, 1.1), y = c(0, 0, 125, 125, 125, 135, 210, 200, 220, 135, 210, 295, 295, 220, 295, 370) ) ggplot() + # 绘制链路 geom_polygon(data = flows, aes(x = x, y = y, group = flow_id, fill = factor(flow_id)), alpha = 0.6) + # 绘制节点 geom_rect(data = nodes, aes(xmin = x - width, xmax = x + width, ymin = y, ymax = ymax), fill = "gray20") + # 添加节点标签 geom_text(data = nodes, aes(x = x, y = (y + ymax)/2, label = name), color = "white", size = 3.5) + # 调整样式 theme_minimal() + theme(legend.position = "none", axis.text = element_blank(), axis.title = element_blank())
如果有多步匹配,只需要新增x>2的层级节点和对应链路坐标即可,代码可复用性高。
内容的提问来源于stack exchange,提问作者L Smeets
相关产品推荐
相关产品推荐

