You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R的sankeyNetwork中添加(log10)P值连线宽度图例?

给networkD3桑基图添加连线宽度图例

可以通过扩展onRender中的JavaScript代码,直接在桑基图的SVG容器里绘制自定义的宽度图例。以下是修改后的完整代码,已集成图例绘制逻辑:

library(networkD3)
library(htmlwidgets)
library(webshot)

# 读取数据(保留原有逻辑)
data <- read.csv("sankeydata.csv")
path <- unique(as.character(data$to))
nodes <- data.frame(node = c(0:43), 
                    name = c(path, "T0", "F_T24", "F_T72", "F_T96", "P_T24", "P_T48"))

links <- data[ , c("node.x", "node.y", "logpvalue")]
colnames(links) <- c("source", "target", "logpvalue")

# 创建桑基图(调整右侧边距预留图例空间)
sn <- sankeyNetwork(Links = links, Nodes = nodes,
                    Source = "target", Target = "source",
                    Value = "logpvalue", NodeID = "name", fontFamily = "Arial",
                    fontSize= 12, nodeWidth = 20, margin = list(left = 260, right = 150))

# 扩展JS逻辑:调整文本对齐 + 添加宽度图例
sankey <- onRender(
  sn,
  '
  function(el, x) {
    // 原有文本对齐调整
    d3.selectAll(".node text").attr("text-anchor", "begin").attr("x", 21);
    
    // 绘制连线宽度图例
    var svg = d3.select(el).select("svg");
    var margin = {right: 100, top: 20};
    var legendWidth = 120;
    var legendHeight = 150;
    
    // 创建图例容器,放置在右上角
    var legend = svg.append("g")
      .attr("transform", "translate(" + (svg.attr("width") - margin.right - legendWidth) + "," + margin.top + ")");
    
    // 获取logpvalue的范围,选取关键刻度(可按需修改)
    var values = x.links.map(d => d.logpvalue);
    var minVal = d3.min(values);
    var maxVal = d3.max(values);
    var midVal = (minVal + maxVal) / 2;
    var legendVals = [minVal, midVal, maxVal];
    
    // 匹配桑基图的宽度缩放逻辑
    var widthScale = d3.scaleLinear()
      .domain([0, maxVal])
      .range([1, 20]); // 对应桑基图连线的最小/最大宽度,可根据实际效果调整
    
    // 绘制图例线条和文本标签
    legendVals.forEach((val, i) => {
      var y = i * 40;
      // 绘制对应宽度的线条
      legend.append("line")
        .attr("x1", 0)
        .attr("x2", legendWidth - 40)
        .attr("y1", y + 5)
        .attr("y2", y + 5)
        .attr("stroke", "#ccc")
        .attr("stroke-width", widthScale(val));
      // 绘制数值标签
      legend.append("text")
        .attr("x", legendWidth - 30)
        .attr("y", y + 10)
        .attr("font-size", "10px")
        .attr("font-family", "Arial")
        .text(val.toFixed(1)); // 保留1位小数,按需调整
    });
    
    // 添加图例标题
    legend.append("text")
      .attr("x", 0)
      .attr("y", -5)
      .attr("font-size", "12px")
      .attr("font-weight", "bold")
      .attr("font-family", "Arial")
      .text("log10(P值)");
  }
  '
)

# 显示桑基图
sankey

# 保存为图片(需先保存完整HTML再截图)
saveWidget(sankey, "sankey.html")
webshot("sankey.html", "sankeySO.png")

关键调整说明:

  • 给sankeyNetwork增加了右侧边距,避免图例与桑基图主体重叠
  • 在JS逻辑中:
    1. 提取所有连线的logpvalue值,计算出最小、中间、最大值作为图例刻度
    2. 用线性比例尺匹配桑基图的连线宽度缩放规则,保证图例宽度与实际连线一致
    3. 在SVG右上角绘制不同宽度的参考线和对应数值,添加图例标题
  • 优化了图片保存流程,确保包含图例的完整内容被截图

你可以根据实际的logpvalue分布,修改legendVals里的刻度值,或者调整widthScale的范围参数,让图例和桑基图的匹配度更高。

内容的提问来源于stack exchange,提问作者Larissa Carvalho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 17:07:38