R语言Sankey图优化:标签外置与节点按流量降序排列
R语言桑基图优化:标签移至图外+节点按流量排序
1. 节点按流量从大到小排序
桑基图的节点顺序由nodes数据框的行序决定,我们需要先计算每个节点的总流量(流入+流出之和),再按总流量降序重新排列节点:
核心步骤:
- 按
links$source分组求和,得到每个节点的流出总量 - 按
links$target分组求和,得到每个节点的流入总量 - 合并流入流出数据,计算每个节点的总流量
- 按总流量降序排序节点,同步更新
links中的源/目标节点索引
代码示例(基于networkD3包):
library(networkD3) library(dplyr) # 模拟都市圈流量数据(替换成你的真实数据) nodes <- data.frame(name = c("城市A", "城市B", "城市C", "城市D", "城市E", "城市F")) links <- data.frame( source = c(0, 0, 1, 1, 2, 3), target = c(3, 4, 3, 5, 4, 5), value = c(50, 30, 40, 20, 25, 35) ) # 计算节点总流量 out_flow <- links %>% group_by(source) %>% summarise(out = sum(value)) %>% rename(id = source) in_flow <- links %>% group_by(target) %>% summarise(`in` = sum(value)) %>% rename(id = target) node_flow <- full_join(out_flow, in_flow, by = "id") %>% mutate( out = ifelse(is.na(out), 0, out), `in` = ifelse(is.na(`in`), 0, `in`), total = out + `in` ) %>% left_join(nodes %>% mutate(id = row_number()-1), by = "id") %>% arrange(desc(total)) # 更新排序后的nodes和links nodes_sorted <- node_flow %>% select(name) links_sorted <- links %>% mutate( source = match(nodes$name[source+1], nodes_sorted$name) - 1, target = match(nodes$name[target+1], nodes_sorted$name) - 1 )
2. 将标签移至图外
通过调整图的边距预留空间,再用JS代码修改标签的位置和对齐方式,让标签完全显示在节点外侧:
代码示例:
# 绘制基础桑基图,加大左右边距 sankey <- sankeyNetwork( Links = links_sorted, Nodes = nodes_sorted, Source = "source", Target = "target", Value = "value", NodeID = "name", fontSize = 14, nodeWidth = 20, nodePadding = 30, margin = list(left = 120, right = 120, top = 30, bottom = 30) ) # 用onRender调整标签位置 library(htmlwidgets) sankey %>% onRender(" function(el) { d3.select(el).selectAll('.node text') .attr('x', function(d) { return d.x < el.offsetWidth / 2 ? -10 : 10; }) .attr('text-anchor', function(d) { return d.x < el.offsetWidth / 2 ? 'end' : 'start'; }); } ")
说明:
margin参数加大左右边距,避免标签被画布截断- JS代码会自动判断节点位置:左侧节点标签右对齐并向左偏移,右侧节点标签左对齐并向右偏移,确保标签完全显示在图外
内容的提问来源于stack exchange,提问作者Jessica Lima
相关产品推荐
相关产品推荐

