使用networkD3绘制桑基图时如何为链路和节点添加固定显示的数值标签
networkD3桑基图固定显示数值标签的实现方法
networkD3的sankeyNetwork函数本身没有内置固定显示链路/节点数值的参数,可通过以下两种方案实现需求:
方案1:基于现有networkD3代码添加JS注入实现固定标签
不需要更换绘图包,在原有代码基础上通过htmlwidgets注入JavaScript代码,在渲染完成后主动添加永久显示的文本标签,完整代码如下:
library(networkD3) library(dplyr) library(htmlwidgets) links <- FinalFlow # 构建节点数据框 nodes <- data.frame( name=c(as.character(links$From), as.character(links$To)) %>% unique() ) # 转换为networkD3要求的ID格式 links$IDsource <- match(links$From, nodes$name)-1 links$IDtarget <- match(links$To, nodes$name)-1 links$group <- as.factor(c(rep(c("T1", "T2", "T3"), 9))) nodes$group <- as.factor(c("my_unique_group")) # 配置颜色 my_color <- 'd3.scaleOrdinal() .domain(["T1", "T2","T3", "my_unique_group"]) .range(["#69b3a2", "steelblue", "grey"])' # 绘制基础桑基图 p <- sankeyNetwork(Links = links, Nodes = nodes, Source = "IDsource", Target = "IDtarget", Value = "MaterialFlow", NodeID = "name", units = "Ton", fontSize = 12, nodeWidth = 30, colourScale = my_color) # 注入JS添加固定标签 p <- onRender(p, ' function(el, x) { // 添加链路数值标签 var links = d3.select(el).selectAll(".link"); links.append("text") .attr("x", function(d) { return (d.source.x1 + d.target.x0) / 2; }) .attr("y", function(d) { return d.y0 + (d.y1 - d.y0) / 2; }) .attr("dy", "0.35em") .attr("text-anchor", "middle") .attr("font-size", "10px") .attr("fill", "#000000") .text(function(d) { return d.value + " Ton"; }); // 如需添加节点数值标签,取消下方代码注释即可 /* var nodes = d3.select(el).selectAll(".node"); nodes.append("text") .attr("x", function(d) { return d.x < (x.options.width / 2) ? d.x1 + 6 : d.x0 - 6; }) .attr("y", function(d) { return (d.y1 + d.y0) / 2; }) .attr("dy", "0.35em") .attr("text-anchor", function(d) { return d.x < (x.options.width / 2) ? "start" : "end"; }) .attr("font-size", "12px") .attr("fill", "#000000") .text(function(d) { return d.name + ": " + d.value + " Ton"; }); */ } ') # 查看效果 p
导出带标签的图片方法
networkD3是HTML交互式控件,普通截图/导出函数无法捕获动态生成的标签,需用webshot2包渲染后导出:
# 首次使用需安装依赖 # install.packages("webshot2") # webshot2::install_chromium() # 先保存为HTML文件,再渲染导出为图片 saveWidget(p, "sankey_temp.html") webshot2::webshot("sankey_temp.html", file = "sankey_with_labels.png", vwidth = 1200, vheight = 800, zoom = 2)
方案2:换用ggsankey包绘制静态桑基图(更适合导出场景)
如果不需要交互功能,更推荐使用ggplot2生态的ggsankey包绘图,天生支持固定标签,导出更便捷:
# 首次使用需安装依赖 # install.packages("ggplot2") # install.packages("ggsankey") library(ggplot2) library(ggsankey) ggplot(links, aes(y = MaterialFlow, axis1 = From, axis2 = To)) + geom_sankey(aes(fill = group), flow.alpha = 0.7, node.color = "black") + # 添加链路数值标签 geom_sankey_label(aes(label = paste0(MaterialFlow, " Ton")), size = 3.5, fill = "white") + # 配置颜色和主题 scale_fill_manual(values = c("T1" = "#69b3a2", "T2" = "steelblue", "T3" = "grey")) + theme_bw() + labs(x = NULL) + theme(axis.text.y = element_blank(), axis.ticks.y = element_blank(), panel.grid = element_blank()) # 直接导出即可,标签完整保留 ggsave("sankey_static.png", width = 12, height = 8, dpi = 300)
内容的提问来源于stack exchange,提问作者Kazi Masel
相关产品推荐
相关产品推荐

