桑基图(Sankey Diagram),又叫桑基能量分流图,核心用途是展示分流,既可以用于路径分析,也可以用于结构分析,如电商消费路径分析、APP用户旅途分析、财务资金支出分析、客群迁移分析等。
# 导入工具包
import numpy as np
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Sankey
%matplotlib inline
# 创建示例数据
customer_level = pd.DataFrame({
'cst_grp_from': ['1月_M0','1月_M0','1月_M0','1月_M1','1月_M1','1月_M1','1月_M1','1月_M1','1月_M2','1月_M2','1月_M2','1月_M2','1月_M2','1月_M2','1月_M3','1月_M3','1月_M3','1月_M3','1月_M3','1月_M3'],
'cst_grp_to': ['2月_M0','2月_M1','2月_M2','2月_M0','2月_M1','2月_M2','2月_M3','2月_M4','2月_M0','2月_M1','2月_M2','2月_M3','2月_M4','2月_M5','2月_M0','2月_M1','2月_M2','2月_M3','2月_M4','2月_M5'],
'cnt': np.random.randint(10000, 50000, 20)
})
customer_level
| cst_grp_from | cst_grp_to | cnt | |
|---|---|---|---|
| 0 | 1月_M0 | 2月_M0 | 23911 |
| 1 | 1月_M0 | 2月_M1 | 28694 |
| 2 | 1月_M0 | 2月_M2 | 39002 |
| 3 | 1月_M1 | 2月_M0 | 37833 |
| 4 | 1月_M1 | 2月_M1 | 13531 |
| 5 | 1月_M1 | 2月_M2 | 26867 |
| 6 | 1月_M1 | 2月_M3 | 18077 |
| 7 | 1月_M1 | 2月_M4 | 13527 |
| 8 | 1月_M2 | 2月_M0 | 15137 |
| 9 | 1月_M2 | 2月_M1 | 18254 |
| 10 | 1月_M2 | 2月_M2 | 22545 |
| 11 | 1月_M2 | 2月_M3 | 40179 |
| 12 | 1月_M2 | 2月_M4 | 34662 |
| 13 | 1月_M2 | 2月_M5 | 38283 |
| 14 | 1月_M3 | 2月_M0 | 39541 |
| 15 | 1月_M3 | 2月_M1 | 18016 |
| 16 | 1月_M3 | 2月_M2 | 30715 |
| 17 | 1月_M3 | 2月_M3 | 37606 |
| 18 | 1月_M3 | 2月_M4 | 45647 |
| 19 | 1月_M3 | 2月_M5 | 29811 |
# 创建nodes
node_contents = sorted(list(set(customer_level['cst_grp_from'].tolist() + customer_level['cst_grp_to'].tolist())))
nodes = [{'name': x} for x in node_contents]
nodes
[{'name': '1月_M0'},
{'name': '1月_M1'},
{'name': '1月_M2'},
{'name': '1月_M3'},
{'name': '2月_M0'},
{'name': '2月_M1'},
{'name': '2月_M2'},
{'name': '2月_M3'},
{'name': '2月_M4'},
{'name': '2月_M5'}]
# 创建links
links = [{'source': x, 'target': y, 'value': z} for x, y, z in zip(customer_level['cst_grp_from'], customer_level['cst_grp_to'], customer_level['cnt'])]
links
[{'source': '1月_M0', 'target': '2月_M0', 'value': 23911},
{'source': '1月_M0', 'target': '2月_M1', 'value': 28694},
{'source': '1月_M0', 'target': '2月_M2', 'value': 39002},
{'source': '1月_M1', 'target': '2月_M0', 'value': 37833},
{'source': '1月_M1', 'target': '2月_M1', 'value': 13531},
{'source': '1月_M1', 'target': '2月_M2', 'value': 26867},
{'source': '1月_M1', 'target': '2月_M3', 'value': 18077},
{'source': '1月_M1', 'target': '2月_M4', 'value': 13527},
{'source': '1月_M2', 'target': '2月_M0', 'value': 15137},
{'source': '1月_M2', 'target': '2月_M1', 'value': 18254},
{'source': '1月_M2', 'target': '2月_M2', 'value': 22545},
{'source': '1月_M2', 'target': '2月_M3', 'value': 40179},
{'source': '1月_M2', 'target': '2月_M4', 'value': 34662},
{'source': '1月_M2', 'target': '2月_M5', 'value': 38283},
{'source': '1月_M3', 'target': '2月_M0', 'value': 39541},
{'source': '1月_M3', 'target': '2月_M1', 'value': 18016},
{'source': '1月_M3', 'target': '2月_M2', 'value': 30715},
{'source': '1月_M3', 'target': '2月_M3', 'value': 37606},
{'source': '1月_M3', 'target': '2月_M4', 'value': 45647},
{'source': '1月_M3', 'target': '2月_M5', 'value': 29811}]
# 创建桑基图
sankey = (
Sankey()
.add(
series_name='',
nodes=nodes,
links=links,
linestyle_opt=opts.LineStyleOpts(opacity=0.3, curve=0.4, color="source"),
label_opts=opts.LabelOpts(position="right"),
)
.set_global_opts(title_opts=opts.TitleOpts(title="用户等级迁移"))
)
# 在notebook中显示
sankey.render_notebook()
# 保存到本地
sankey.render("桑基图_用户等级迁移.html")
'C:\\Users\\sheng\\OneDrive\\个人\\博客\\博客文章\\Python绘制桑基图\\桑基图_用户等级迁移.html'
# 创建示例数据
phone_bank_page = pd.DataFrame({
'page_from': ['首页','理财产品','理财产品','首页','掌上商城','掌上商城','掌上商城','首页','闪电贷','首页','热门活动','热门活动','热门活动','首页','金葵权益','金葵权益','金葵权益','首页','信用卡首页'],
'page_to': ['理财产品','活钱管理','稳中求进','掌上商城','华为','百万补贴','每日特惠','闪电贷','了解闪电贷','热门活动','高颜值信用卡榜单','M+会员升级礼','答题赚奖励','金葵权益','M+会员权益','周三五折享美食','达标领好礼','信用卡首页','推荐办卡'],
'cnt': np.random.randint(100000, 500000, 19)
})
phone_bank_page
| page_from | page_to | cnt | |
|---|---|---|---|
| 0 | 首页 | 理财产品 | 223283 |
| 1 | 理财产品 | 活钱管理 | 327386 |
| 2 | 理财产品 | 稳中求进 | 193396 |
| 3 | 首页 | 掌上商城 | 494217 |
| 4 | 掌上商城 | 华为 | 454157 |
| 5 | 掌上商城 | 百万补贴 | 212092 |
| 6 | 掌上商城 | 每日特惠 | 480816 |
| 7 | 首页 | 闪电贷 | 483858 |
| 8 | 闪电贷 | 了解闪电贷 | 269219 |
| 9 | 首页 | 热门活动 | 279590 |
| 10 | 热门活动 | 高颜值信用卡榜单 | 243339 |
| 11 | 热门活动 | M+会员升级礼 | 132135 |
| 12 | 热门活动 | 答题赚奖励 | 233573 |
| 13 | 首页 | 金葵权益 | 436562 |
| 14 | 金葵权益 | M+会员权益 | 275921 |
| 15 | 金葵权益 | 周三五折享美食 | 374569 |
| 16 | 金葵权益 | 达标领好礼 | 359132 |
| 17 | 首页 | 信用卡首页 | 136130 |
| 18 | 信用卡首页 | 推荐办卡 | 349357 |
# 创建nodes
node_contents = list(set(phone_bank_page['page_from'].to_list() + phone_bank_page['page_to'].to_list()))
nodes = [{'name': x} for x in node_contents]
nodes
[{'name': '活钱管理'},
{'name': '达标领好礼'},
{'name': '掌上商城'},
{'name': 'M+会员权益'},
{'name': '首页'},
{'name': '信用卡首页'},
{'name': '高颜值信用卡榜单'},
{'name': '热门活动'},
{'name': '华为'},
{'name': '闪电贷'},
{'name': '了解闪电贷'},
{'name': '理财产品'},
{'name': '答题赚奖励'},
{'name': '金葵权益'},
{'name': '百万补贴'},
{'name': 'M+会员升级礼'},
{'name': '稳中求进'},
{'name': '每日特惠'},
{'name': '周三五折享美食'},
{'name': '推荐办卡'}]
# 创建links
links = [{'source': x, 'target': y, 'value': z} for x, y, z in zip(phone_bank_page['page_from'], phone_bank_page['page_to'], phone_bank_page['cnt'])]
links
[{'source': '首页', 'target': '理财产品', 'value': 223283},
{'source': '理财产品', 'target': '活钱管理', 'value': 327386},
{'source': '理财产品', 'target': '稳中求进', 'value': 193396},
{'source': '首页', 'target': '掌上商城', 'value': 494217},
{'source': '掌上商城', 'target': '华为', 'value': 454157},
{'source': '掌上商城', 'target': '百万补贴', 'value': 212092},
{'source': '掌上商城', 'target': '每日特惠', 'value': 480816},
{'source': '首页', 'target': '闪电贷', 'value': 483858},
{'source': '闪电贷', 'target': '了解闪电贷', 'value': 269219},
{'source': '首页', 'target': '热门活动', 'value': 279590},
{'source': '热门活动', 'target': '高颜值信用卡榜单', 'value': 243339},
{'source': '热门活动', 'target': 'M+会员升级礼', 'value': 132135},
{'source': '热门活动', 'target': '答题赚奖励', 'value': 233573},
{'source': '首页', 'target': '金葵权益', 'value': 436562},
{'source': '金葵权益', 'target': 'M+会员权益', 'value': 275921},
{'source': '金葵权益', 'target': '周三五折享美食', 'value': 374569},
{'source': '金葵权益', 'target': '达标领好礼', 'value': 359132},
{'source': '首页', 'target': '信用卡首页', 'value': 136130},
{'source': '信用卡首页', 'target': '推荐办卡', 'value': 349357}]
# 创建桑基图
sankey = (
Sankey()
.add(
series_name='',
nodes=nodes,
links=links,
linestyle_opt=opts.LineStyleOpts(opacity=0.3, curve=0.4, color="source"),
label_opts=opts.LabelOpts(position="right"),
)
.set_global_opts(title_opts=opts.TitleOpts(title="手机银行页面流转"))
)
# 在notebook中显示
sankey.render_notebook()
# 保存到本地
sankey.render("桑基图_手机银行页面流转.html")
'C:\\Users\\sheng\\OneDrive\\个人\\博客\\博客文章\\Python绘制桑基图\\桑基图_手机银行页面流转.html'