多维度下桑基图的自动生成与流转分析:看清用户每一步流失去哪了
2026/9/22 1:10:50 网站建设 项目流程

多维度下桑基图的自动生成与流转分析:看清用户每一步流失去哪了

在分析复杂的用户全生命周期旅程、多渠道流量流转、或者资金账户的多级划拨时,传统的分组柱状图和漏斗图(Funnel Chart)往往会显得力不从心。

标准的漏斗图有一个致命的假设:它假设用户的行为是严格线性的单向流动(例如:曝光 -> 进店 -> 加购 -> 支付)
然而真实的商业世界中,用户的流转是极其错综复杂的分支网络:

  • 从“首页推荐”进来的用户,有人直接跳去了“搜索”,有人跳去了“领券中心”,有人逛了一圈跑去“直播间”,最后在“购物车”完成结算;
  • 还有大量用户在某些节点发生跳出流失、或者逆向回流。

当我们需要在一张图里同时呈现多节点之间的分流比例、流向路径宽度与最终归宿时,**桑基图(Sankey Diagram)**是无可争议的可视化王者。

今天我们深入拆解桑基图在多维度用户流转分析中的自动化生成算法,以及如何用代码直接输出企业级 ECharts 桑基图配置。


桑基图的核心拓扑结构:节点(Nodes)与连接边(Links)

桑基图在底层本质上是一个有向加权图(Directed Weighted Graph)。它只由两个基础数据集构成:

+-----------------------------------------------------------------------------------------------+ | 1. 节点列表 (Nodes): 包含每个唯一节点的名称与属性 | | - [ {name: "首页"}, {name: "搜索页"}, {name: "商品详情"}, {name: "直接流失"} ] | | | | 2. 边列表 (Links / Edges): 包含流量的起点 (Source)、终点 (Target) 及流量大小 (Value) | | - [ {source: "首页", target: "搜索页", value: 50000}, | | {source: "首页", target: "直接流失", value: 30000}, | | {source: "搜索页", target: "商品详情", value: 42000} ] | +-----------------------------------------------------------------------------------------------+

自动化数据转换实战:从用户时序路径到桑基图拓扑

假设数仓提供了一张记录用户连续三步访问行为的明细表df_user_journey

import pandas as pd import json # 模拟用户前三步访问节点数据 data = [ {"step1": "首页", "step2": "搜索页", "step3": "商品详情", "users": 45000}, {"step1": "首页", "step2": "搜索页", "step3": "离开App", "users": 15000}, {"step1": "首页", "step2": "领券中心", "step3": "商品详情", "users": 20000}, {"step1": "首页", "step2": "领券中心", "step3": "离开App", "users": 10000}, {"step1": "首页", "step2": "离开App", "step3": "离开App", "users": 30000}, {"step1": "外部广告", "step2": "商品详情", "step3": "支付完成", "users": 12000}, {"step1": "外部广告", "step2": "商品详情", "step3": "离开App", "users": 18000}, ] df = pd.DataFrame(data)

核心转换算法:带阶段前缀的拓扑构建

避坑关键:如果用户在第 1 步访问了“商品详情”,在第 2 步也访问了“商品详情”,如果在桑基图里直接用同名节点"商品详情",会导致图表中出现自环(Cycle),ECharts 渲染时会直接崩溃报错!
因此,在自动化构建算法中,必须为节点自动加上阶段前缀(如"S1:商品详情""S2:商品详情"),而在前端展示时通过formatter剥离前缀:

def generate_sankey_data(df: pd.DataFrame, step_cols: list, value_col: str) -> dict: links = [] nodes_set = set() for i in range(len(step_cols) - 1): source_col = step_cols[i] target_col = step_cols[i + 1] # 按相邻两个阶段聚合流量 grouped = df.groupby([source_col, target_col])[value_col].sum().reset_index() for _, row in grouped.iterrows(): # 增加阶段编号前缀,防止跨阶段同名节点产生死循环 src_node = f"[第{i+1}步] {row[source_col]}" tgt_node = f"[第{i+2}步] {row[target_col]}" val = int(row[value_col]) if val > 0: nodes_set.add(src_node) nodes_set.add(tgt_node) links.append({ "source": src_node, "target": tgt_node, "value": val }) nodes = [{"name": n} for n in sorted(list(nodes_set))] return { "nodes": nodes, "links": links }

ECharts 高级桑基图配置与渐变色美化

将算法生成的 JSON 载入 ECharts,配合流畅的曲线曲率(curveness)与悬浮高亮:

const sankeyData = getSankeyDataFromBackend(); const option = { title: { text: '用户全站流转与跳出路径桑基图', subtext: '基于 Q3 季度前三步核心转化链路' }, tooltip: { trigger: 'item', triggerOn: 'mousemove', formatter: function(params) { if (params.dataType === 'edge') { return `${params.data.source} ➔ ${params.data.target}<br/><b>流转用户数: ${params.data.value.toLocaleString()} 人</b>`; } return `<b>${params.name}</b><br/>总吞吐流量: ${params.value.toLocaleString()} 人`; } }, series: [{ type: 'sankey', layout: 'none', emphasis: { focus: 'adjacency' // 核心交互:鼠标悬浮时高亮关联的上下游流动,淡化无关节点 }, nodeWidth: 20, // 节点柱子宽度 nodeGap: 14, // 纵向节点间距 orient: 'horizontal', draggable: true, // 允许用户手动拖拽调整节点位置 lineStyle: { color: 'gradient', // 优雅的源节点到目标节点渐变色彩 curveness: 0.5, opacity: 0.4 }, label: { color: '#333333', fontSize: 12 }, data: sankeyData.nodes, links: sankeyData.links }] };

桑基图落地的三条设计军规

  1. 阶段深度不超过 5 层:桑基图最适合展现 3 到 5 个关键阶段的流转。如果强行把 10 步路径全部画在一张图里,右侧的流线会细成乱麻,失去宏观洞察价值。
  2. 长尾微小流量必须归并为“其他”:如果某个分支的流量占比低于总体大盘的 1%,算法应当自动将其合并为"[第N步] 其他流向",避免几百条细如发丝的线条干扰主链路分析。
  3. 流失节点显式独立着色:将所有代表跳出和流失的节点(如离开App未支付关闭)统一配置为醒目的灰色或浅红色,业务人员一眼就能识别出哪个环节是主要的“漏水大管子”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询