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

Python实现多级桑基图(Sankey Plot)求助:复现目标图与关键步骤解析

Python实现多级桑基图(Sankey Plot)求助:复现目标图与关键步骤解析

嗨,我来帮你搞定这个桑基图的复现问题!先拆解你当前代码的核心bug,再一步步讲透桑基图的关键实现步骤,最后给你可以直接跑的修正版代码~

你的现有代码核心问题分析

  • 最致命的坑点:Plotly的Sankey图要求source和target必须是节点的数字索引,而不是原数据里的文本标签!你直接用了sank['FROM']和sank['TO']的字符串值,这会导致Plotly完全无法识别节点对应关系,肯定出不来正确的图。
  • 小语法错误:label = sank['FROM'].unique().tolist() + sank['TO'].unique().tolist(), 最后多了个逗号,会让label变成元组而非列表,也会引发异常。
  • 节点去重不严谨:直接拼接FROM和TO的唯一值,可能会产生重复节点(比如某个节点既是起点又是终点),导致节点列表冗余。

桑基图复现的关键步骤(敲黑板!)

不管是几级桑基图,这几个步骤都是绕不开的核心:

1. 节点映射:文本→数字索引

桑基图的底层逻辑是用数字索引关联节点与连线,这是新手最容易踩坑的地方:

  • 收集所有出现过的节点(包含所有FROM和TO的取值)并去重
  • 给每个唯一节点分配一个专属的数字ID
  • 把原数据中的FROM/TO列转换成对应的数字索引值

2. 数据层级校验

确保你的数据是相邻层级的转移关系(比如从第一分类到第二分类,第二到第三,不能跳级),这是桑基图层级清晰的前提。

3. 样式匹配目标图

根据目标图调整节点的颜色、厚度,连线的透明度、颜色,还有节点的间距(pad)等参数,让视觉效果更贴近预期。

修正后的可运行代码

假设你已经用Pandas读取了数据集到sank DataFrame里,代码如下(每一步都加了注释):

import plotly.graph_objects as go
import pandas as pd

# ---------------------- 1. 核心:节点映射处理 ----------------------
# 收集所有唯一节点(自动去重)
all_nodes = pd.concat([sank['FROM'], sank['TO']]).unique()
# 给每个节点分配唯一索引ID
node_mapping = {node: idx for idx, node in enumerate(all_nodes)}
# 把原数据的FROM/TO转换为索引值(这是你之前代码缺失的关键步骤!)
sank['source_idx'] = sank['FROM'].map(node_mapping)
sank['target_idx'] = sank['TO'].map(node_mapping)
# 准备节点标签列表
node_labels = list(node_mapping.keys())

# ---------------------- 2. 构建桑基图 ----------------------
fig = go.Figure(data=[go.Sankey(
    node=dict(
        pad=15,  # 节点之间的间距,和目标图匹配
        thickness=20,  # 节点厚度
        line=dict(color="black", width=0.5),  # 节点边框
        label=node_labels,  # 节点显示的文本
        # 可根据节点层级自定义颜色,贴近目标图风格
        color=["#f0f0f0" if node in sank['FROM'].unique() and node not in sank['TO'].unique() 
               else "#cce5ff" for node in node_labels]
    ),
    link=dict(
        source=sank['source_idx'],  # 必须用数字索引,不能用文本!
        target=sank['target_idx'],  # 同上
        value=sank['VALUE'],  # 连线宽度对应数值
        # 连线用半透明色,和节点颜色呼应
        color="rgba(204, 229, 255, 0.6)"
    )
)])

# 调整布局细节
fig.update_layout(
    title_text="复现的多级桑基图",
    font_size=12,
    title_x=0.5  # 标题居中
)

# 显示图形
fig.show()

额外注意事项

  • 如果你的目标图是三级或更多级,只要数据里的转移关系是相邻层级的,这个代码逻辑完全适用,不需要额外修改节点映射部分。
  • 要是想让不同层级的节点颜色区分更明显,可以根据节点在数据中的出现范围(比如只出现在FROM的是起始级,只出现在TO的是终止级)来设置颜色规则。
  • 节点映射的去重处理已经帮你解决了重复节点的问题,不会出现同一个节点在图里显示多次的情况。

备注:内容来源于stack exchange,提问作者Mik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:33:03