数据可视化-桑基图(Sankey)

作者: 洗洗睡吧i | 来源:发表于2020-04-21 18:37 被阅读0次

1. 桑基图(Sankey)介绍

sankey图可用于数据从一系列节点到另一系列节点流入流出的可视化。

主要有两个基本概念:

  • 节点 (nodes)
  • 连接 (links): 源节点至目标节点之间的关系,每个连接包括三个元素:
    • source: 源节点
    • target: 目标节点
    • value: 数据

ref: https://developers.google.com/chart/interactive/docs/gallery/sankey

2. 绘制桑基图(使用pyecharts)

常用的绘图库 matplotlib, seaborn 好像不支持桑基图, 这里使用了 pyecharts 。

这里https://gallery.pyecharts.org/#/Sankey/sankey_base有几个例子。

简单用法如下:

import pandas as pd

from pyecharts import options as opts
from pyecharts.charts import Sankey

# 数据
data = [[ 'Brazil', 'Portugal', 5 ],
       [ 'Brazil', 'France', 1 ],
       [ 'Brazil', 'Spain', 1 ],
       [ 'Brazil', 'England', 1 ],
       [ 'Canada', 'Portugal', 1 ],
       [ 'Canada', 'France', 5 ],
       [ 'Canada', 'England', 1 ],
       [ 'Mexico', 'Portugal', 1 ],
       [ 'Mexico', 'France', 1 ],
       [ 'Mexico', 'Spain', 5 ],
       [ 'Mexico', 'England', 1 ],
       [ 'USA', 'Portugal', 1 ],
       [ 'USA', 'France', 1 ],
       [ 'USA', 'Spain', 1 ],
       [ 'USA', 'England', 5 ],
       [ 'Portugal', 'Angola', 2 ],
       [ 'Portugal', 'Senegal', 1 ],
       [ 'Portugal', 'Morocco', 1 ],
       [ 'Portugal', 'South Africa', 3 ],
       [ 'France', 'Angola', 1 ],
       [ 'France', 'Senegal', 3 ],
       [ 'France', 'Mali', 3 ],
       [ 'France', 'Morocco', 3 ],
       [ 'France', 'South Africa', 1 ],
       [ 'Spain', 'Senegal', 1 ],
       [ 'Spain', 'Morocco', 3 ],
       [ 'Spain', 'South Africa', 1 ],
       [ 'England', 'Angola', 1 ],
       [ 'England', 'Senegal', 1 ],
       [ 'England', 'Morocco', 2 ],
       [ 'England', 'South Africa', 7 ],
       [ 'South Africa', 'China', 5 ],
       [ 'South Africa', 'India', 1 ],
       [ 'South Africa', 'Japan', 3 ],
       [ 'Angola', 'China', 5 ],
       [ 'Angola', 'India', 1 ],
       [ 'Angola', 'Japan', 3 ],
       [ 'Senegal', 'China', 5 ],
       [ 'Senegal', 'India', 1 ],
       [ 'Senegal', 'Japan', 3 ],
       [ 'Mali', 'China', 5 ],
       [ 'Mali', 'India', 1 ],
       [ 'Mali', 'Japan', 3 ],
       [ 'Morocco', 'China', 5 ],
       [ 'Morocco', 'India', 1 ],
       [ 'Morocco', 'Japan', 3 ]]

df = pd.DataFrame(data, columns=['source', 'target', 'value'])
print('- data shape: ', df.shape, '\n')

# 生成节点, 先合并源节点和目标节点,然后去除重复的节点,最后输出成 dict 形式
nn = pd.concat([df['source'], df['target']])
nn = nn.drop_duplicates()
nodes = pd.DataFrame(nn, columns=['name']).to_dict(orient='records')
print('- nodes:\n', nodes, '\n')

# 生成连接, dict 形式
links = df.to_dict(orient='records')
print('- links:\n', links, '\n')

# 绘制桑基图
sk =(
    Sankey(init_opts=opts.InitOpts(width="800px", height="600px")) # 页面大小
    .add(
        series_name="legend", # legend
        nodes=nodes,
        links=links,
        # opacity 透明度; curve 弯曲程度; color 色系
        linestyle_opt=opts.LineStyleOpts(opacity=0.2, curve=0.5, color="source"), 
        label_opts=opts.LabelOpts(position="right"), # 节点名称
    )
    .set_global_opts(title_opts=opts.TitleOpts(title="sankey")) # 标题
    .render("sankey.html") # 保存成 html 文件
)
sankey.png

代码说明:

  • pyecharts的桑基图对于原始数据的格式比较啰嗦,这里用 pandas 处理了一下,还可以修改一下去读取 csv 文件。
  • pyecharts直接保存图片也比较麻烦,需要用 selenium 之类的工具,配置一大堆;可以配但没必要;还不如直接在浏览器截图完事。

使用 D3 绘制

D3 绘制桑基图貌似更简便一点,可惜不能用 python。

https://github.com/d3/d3-sankey

这里还有个在线可实时编辑版。

https://observablehq.com/@mbostock/flow-o-matic

厉害了!

相关文章

网友评论

    本文标题:数据可视化-桑基图(Sankey)

    本文链接:https://www.haomeiwen.com/subject/mvmpihtx.html