数据可视化 Python实现Sankey桑基图

根据不完整统计,90%想用sankey图的朋友都是因为被它炫酷的外表所吸引,举个例子:数据可视化 Python实现Sankey桑基图_第1张图片
关于sankey图的定义是这样描述的:

  • 即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小,通常应用于能源、材料成分、金融等数据的可视化分析。
  • 流程图的一种
  • 由若干个三元素组成(节点,边,流量)
  • 遵循守恒定律,无论怎么流动,开端和末端数据始终一致

下面我们来简单实现一个Sankey图

第一步,我们先收集数据。
这里我在2020意大利新冠肺炎案例统计收集了意大利的患者年龄分布。
我们用pandas库来绘制统计表。当然也可以用excel保存为xlsx文件。

db1 = pd.DataFrame({
    'country':['Italy','Italy','Italy','Italy'],
    'ages':['18岁以下','19-50岁','50-70岁','70岁以上'],
    'confirm':['1677','31394','43617','43139'],
    'Deceased':['167','408','4492','34813'],
    'Active/Recovered': ['1510','30986','39125','8326']
})
print(db1)

那么打印下统计表得到:

 country    ages    confirm     Deceased    Active/Recovered
0   Italy   18岁以下   1677      167         1510
1   Italy   19-50岁   31394     408         30986
2   Italy   50-70岁   43617     4492        39125
3   Italy   70岁以上   43139     34813       8326

如果是要读入excel保存的表格那么只要简单的一行命令:
db1 = pd.read_excel('statistik.xlsx)

第二步,我们开始处理数据
画图按照Sankey图的规则,需要定义节点,边,流量。
可以理解为两个数据结构:nodes和links。

在这个案例,所有节点就是:Italy,18岁以下,19-50岁,50-70岁,50-70岁,confirm,Deceased,Active/Recovered
我们用一个字典嵌套的链表来储存:

nodes=[]
for i in range(2):
    values = db1.iloc[:,i].unique()
    for value in values:
        dic={}
        dic['name'] = value
        nodes.append(dic)
nodes.append({'name':'Deceased'})
nodes.append({'name':'Active/Recovered'})
[{'name': 'Italy'}, {'name': '18岁以下'}, {'name': '19-50岁'}, 
{'name': '50-70岁'}, {'name': '70岁以上'}, {'name': 'Deceased'}, 
{'name': 'Active/Recovered'}]

然后定义边和流量,数据从哪里流向哪里,流量为多少,按照source-target-value的格式保存。我们用循环加字典可以轻松搞定

links = []

for i in db1.values:
    dic={}
    dic['source']=i[0]
    dic['target']=i[1]
    dic['value']=i[2]
    links.append({'source':i[0],'target':i[1],'value':i[2]})
    links.append({'source':i[1],'target':db1.keys()[3],'value':i[3]})
    links.append({'source':i[1],'target':db1.keys()[4],'value':i[4]})
print(links)
[{'source': 'Italy', 'target': '18岁以下', 'value': '1677'},
 {'source': '18岁以下', 'target': 'Deceased', 'value': '167'}, 
 {'source': '18岁以下', 'target': 'Active/Recovered', 'value': '1510'}, 
 {'source': 'Italy', 'target': '19-50岁', 'value': '31394'}, 
 {'source': '19-50岁', 'target': 'Deceased', 'value': '408'},
 {'source': '19-50岁', 'target': 'Active/Recovered', 'value': '30986'}, 
 {'source': 'Italy', 'target': '50-70岁', 'value': '43617'},
{'source': '50-70岁', 'target': 'Deceased', 'value': '4492'},
 {'source': '50-70岁', 'target': 'Active/Recovered', 'value': '39125'}, 
 {'source': 'Italy', 'target': '70岁以上', 'value': '43139'}, 
{'source': '70岁以上', 'target': 'Deceased', 'value': '34813'}, 
{'source': '70岁以上', 'target': 'Active/Recovered', 'value': '8326'}]

nodes和links定义好了之后,就已经完成了80%

第三步,绘图
我们可以使用pyecharts的库来实现,这一段代码几乎是固定的格式

from pyecharts.charts import Sankey
from pyecharts import options as opts
pic = (
    Sankey().add('',
         nodes,
         links,
         linestyle_opt=opts.LineStyleOpts(opacity = 0.3, curve = 0.5, color = 'source'),
         label_opts=opts.LabelOpts(position = 'top'),
         node_gap = 30,

    )
    .set_global_opts(title_opts=opts.TitleOpts(title = '意大利新冠肺炎病患年龄分布'))
)
pic.render('test.html')

好了,到这来大功告成,运行python文件,最后会生成一个test.html。
用浏览器打开就可以欣赏做出来的的sankey图:
数据可视化 Python实现Sankey桑基图_第2张图片

全世界一定会慢慢的战胜疫情,逝者安息。珍惜当下过好自己的每一天。

你可能感兴趣的:(常见问题)