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

如何在Plotly桑基图中无需悬停即可显示节点与链路数值

在Plotly桑基图中直接显示节点和链路的数值

问题背景

在Plotly桑基图中,默认仅能通过悬停查看节点和链路的value值。若直接将节点标签替换为数值,会丢失节点的名称标识,因此需要实现同时显示节点名称和数值,并在链路上直接标注数值的效果。

解决方案

1. 节点显示名称+总数值

先计算每个节点的总流入/流出值,再将节点的label设置为名称\n总数值的格式,即可在节点上同时展示名称和数值。

2. 链路显示数值

Plotly原生go.Sankey不支持直接在链路上标注数值,需通过go.Scatter添加文本注释:

  • 提取桑基图布局中每个节点的位置坐标
  • 计算每条链路的起点(source节点)和终点(target节点)的坐标中点
  • 在中点位置添加对应链路的value文本

修改后的完整代码

import plotly.graph_objects as go
import numpy as np

# 原始数据
node_labels = ["A1", "A2", "B1", "B2", "C1", "C2"]
link_sources = [0, 1, 0, 2, 3, 3]
link_targets = [2, 3, 3, 4, 4, 5]
link_values = [8, 4, 2, 8, 4, 2]

# 计算每个节点的总数值(流入+流出)
node_values = np.zeros(len(node_labels))
for s, t, v in zip(link_sources, link_targets, link_values):
    node_values[s] += v
    node_values[t] += v

# 生成带数值的节点标签
node_labels_with_value = [f"{label}\n{int(val)}" for label, val in zip(node_labels, node_values)]

# 创建桑基图
fig = go.Figure(data=[go.Sankey(
    node=dict(
        pad=15,
        thickness=20,
        line=dict(color="black", width=0.5),
        label=node_labels_with_value,
        customdata=[f"Long name {label}" for label in node_labels],
        hovertemplate='Node %{customdata} has total value %{value}<extra></extra>',
        color="blue"
    ),
    link=dict(
        source=link_sources,
        target=link_targets,
        value=link_values,
        customdata=["q","r","s","t","u","v"],
        hovertemplate='Link from node %{source.customdata}<br />'+ 
          'to node%{target.customdata}<br />has value %{value}'+ 
          '<br />and data %{customdata}<extra></extra>',
    ))])

# 先渲染获取节点坐标(脚本运行时需此步骤,Notebook可直接用fig.full_figure_for_development())
fig.update_layout(title_text="Sankey Diagram with Values Displayed", font_size=10)
fig.show(renderer="browser")

# 提取节点坐标(实际使用时可通过fig.full_figure_for_development()['data'][0]['node']['x/y']获取)
node_x = [0.0, 0.0, 0.5, 0.5, 1.0, 1.0]
node_y = [0.75, 0.25, 0.8333, 0.1667, 0.6667, 0.3333]

# 添加链路数值注释
for s, t, v in zip(link_sources, link_targets, link_values):
    mid_x = (node_x[s] + node_x[t]) / 2
    mid_y = (node_y[s] + node_y[t]) / 2
    fig.add_trace(go.Scatter(
        x=[mid_x], y=[mid_y],
        text=[str(v)],
        mode="text",
        textfont=dict(size=12, color="black"),
        showlegend=False
    ))

fig.show()

效果对比

  • 实际输出(默认效果):
    Actual Output

  • 期望输出(显示数值后):
    Desired Output

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:13:25