Python画境外新冠病例输入桑基图
在国内疫情已经得到了控制并逐渐减少,但是国外的疫情出现大爆发,境外输入的情况也愈加严峻。鉴于新冠肺炎疫情在全球范围快速蔓延,我国自2020年3月28日0时起,暂时停止外国人持目前有效来华签证和居留许可入境。
那目前境外输入病历到到底有多少?都输入了哪些省份呢?相关的数据中,既包含了来源国、输入地,又有各地区输入病例详细数值,不用表格、不用多个柱状图折线图并列,应该如何表达这组数据呢?
这张图既能看到所有来源国和输入地,还能看出每一个数据流动的起点和终点,这就是桑基图,展现数据流动的小能手。
桑基图(Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图。它主要由节点、边和流量三要素构成。
图中延伸的分支的宽度对应数据流量的大小,边越宽代表流量越大。因1898年Matthew Henry Phineas Riall Sankey绘制的"蒸汽机的能源效率图"而闻名,此后便以其名字命名为"桑基图"。
桑基图属于流程图的一种,核心在于展示数据的流转。大家是不是想到漏斗图?漏斗图是有转化流失,而桑基图只是流转,无论怎么流动,开端和末端数据总是一致的,这是他们之间的区别。
我们继续使用pyecharts进行绘制,本文使用v1.x版本进行绘制,如还没安装pyecharts,请先安装。
先导入需要的包跟数据
1import pandas
2from pyecharts.charts import Sankey
3from pyecharts import options as opts
4
5data = pandas.read_excel('D:/python/yq/ly.xlsx',sheet_name='1')
打开data数据框可以查看到数据是这样的
注:数据来源:国家卫健委,北京卫健委,上海卫健委,甘肃卫健委等,截至2020年4月1日,因来源地、输入地众多,所以只取来源地、输入地Top10的地区数据。
So,先要做下数据转换处理,先处理节点数据nodes
nodes = []
for i in set(pandas.concat([data.来源地, data.输入地])):
d1 = {}
d1['name'] = i
nodes.append(d1)
然后再处理边和流量数据links
links = []
for x, y, z in zip(data.来源地, data.输入地, data.数量):
d2 = {}
d2['source'] = x
d2['target'] = y
d2['value'] = z
links.append(d2)
最后就可以画图了
1pic = (
2 #创角桑基图对象,设置画布大小
3 Sankey(init_opts=opts.InitOpts(width="1600px", height="800px"))
4 .add('确诊病例', #图例名称
5 nodes, #节点数据
6 links, #边和流量数据
7 #设置透明度、弯曲度、颜色
8 linestyle_opt=opts.LineStyleOpts(opacity = 0.3, curve = 0.5, color = "source"),
9 label_opts=opts.LabelOpts(position="right"), #标签显示位置
10 node_gap = 10 #节点之前的距离
11 )
12 .set_global_opts(title_opts=opts.TitleOpts(title = 'TOP10境外输入统计'))
13)
14
15pic.render('TOP10境外输入统计.html')
最后就得到了这张图
从图中可以发现几个有趣的地方:
伊朗、沙特病例主要流向甘肃;
西班牙大部分病例主要流向北京;
英国大部分病例主要流向北京、上海、广东;
菲律宾国大部分病例主要流向广东、福建。