数据可视化-桑基图(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