赣州新闻网

首页 / 科技

互链月报 | 广东、湖南3月发布5份区块链扶持政策 产业园建设成发展重点

2020-04-03 · 赣州新闻网 · 科技

作者 | 周志鹏

责编 | 郭 芮

最近,不止一次收到小伙伴的截图追问:

手把手教你用 Python 绘制酷炫的桑基图

“这个图叫什么???”

“这个图真好看!!!怎么画啊?”

......

笔者本没有干货,问的人多了,也便有w I B R了干货。

此图姓桑名基,平素不喜露面。奈e e I w , u ! }何天生丽; h A I / m Y s质,偶有露面,必引众人围观。

时人有云:“桑基桑基,高贵美丽!”

手把手教你用 Python 绘制酷炫的桑基图

桑基是何许图也?

据笔者不严z L j J p ?谨的抽样提问统计,90%想学习桑基图的旁友,都是被她妖艳炫酷的外表所吸引。

而桑基图真正代表了什么?和类似图表相比的独特性是什么?却几乎v + q无人问津。

害!人真的是视觉动物!

言归正传,我们来看看百科的官方解释:

桑基图(Sankey diagram),l J R H i p V即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型k % ? i i ] R ]的流程图,图中延伸的分支的宽度对应数据流量的大小$ e U E q,通常应用于能源、材料成分、金融等数据的可视化分析。因1898年Matthew Hb / % denry PhN z Kineas Riall Sankey绘制的\"蒸汽机的能源效率图\"而闻名,此后便以其名字命名为\"桑基图\"。

Emmm,有点内个意思了,结合其他资料,做进一步的汇总提炼:

  • 桑基两个字取自“发明”者的名字

  • 属于流程图的一种,核心在于展示数据的流转

  • 主要由节点、边和流量三要素构成,边越宽代表流量越大q L T L )

  • 遵循守恒定律,无论怎么流动,开端和末端数据总是一致的

文字太苍白l @ ? i = @,下| G +面我们用Python来绘制一个具体的实例。

手把手教你用 Python 绘制酷炫的桑基图

Python手把手绘制桑基图

动手之前Z F D Y,我们再次敲黑板,回顾桑基图组成X X Y $ : f要素的重点——节点、边和流量。

任何桑基图,无论展现形式如何夸张,色彩如{ C : { 1 G何艳丽,动效如何炫酷,本质都逃不出上述3点。

只要我们定义好上述3个要素,Python的pyecharts库能够轻松实现桑基图的绘制。

这里我们用“当代青年熬夜原因分析”数据为例:

(数据来源:这个数据是笔者近两周卖炒粉时口头做的调研)

手把手教你用 Python 绘制酷炫的桑基图

很规整的性别、熬夜原因、人数三列数据。

不过,要用pyecharts来画图,得入乡随俗,按$ M r P 1照它定的规则来规整数据源。

首先是节点,这一步需要把所有涉及到的节点去重规整在一起。也就是要把性别一列的“男”、“女”和熬夜原因一列的“打游戏”、“加班”、“看剧”以列表内嵌套字典的形式去重汇总:

手把手教你用 Python 绘制酷炫的桑基图

接着,定义边和流量,数据从0 t r 5 K哪里流向哪里,流量(值)是多少,循环+字典依然可以轻松搞定:

手把手教你用 Python 绘制酷炫的桑基图

source-target-vR J # M Q A m Ualue的0 j *字典格式,很清晰的描述了数据的流转情况。

这两块数据准备完毕,桑基图已经完成了80%,剩下的20%,只是固定格式的绘图代码:

from pyecharts.charts import Sankeyfrom2 B . / I k pyecharts import options as opts
pic = ( SanS f . ) {key .add(\'\', #图例名称 nodes, #传y . E入节点数据 linkes, #传入边和流量数据 #设置透明度、弯曲度、颜色 linesR ` r ttyle_opt=opts.LineStyleOpts(opacity = 0.3, curve = 0.5, color = \"source\"), #标签显示位置 label( z ; ? B _opts=opts.LabelOpts(position=\"right\"), #节点之前的距离 node_gap = 30, ) .se, M A x I G vt* v b Y A r z e_gloP * _ 4 { Rbal_opts(t7 L X J 2 F Y c + \"source\"), label_opts=opts.LabelOpts(position=\"top\"a } E 7 _ _), node_ga/ H O N # # 3p = 30, orient=\"vertical\", #S 8 ~ 3 5 T O更改的是这里 ) .set_global_opts(title_opts=opts.Ti` G N + @ ( 7 VtleOD ` E 8 ) A npts(title = \'熬夜原因细分桑基图\')))
pic.rent Y { n z 3 C ~der(\'tes$ X l 4 5 | u ~t2.html\')
手把手教你用 Python 绘制酷炫的桑基图

OK!不过,还有同学意犹未尽,这个是涉及到两层的流转,那如果三层,需要怎么画呢?

不慌,先导入(狗粮)数据:

手把手教你用 Python 绘制酷炫的桑基图

这是某宠物品牌,3月份主要产品购买路径(第( + v * 7 , c一次和第二次; 5 L 7 h -)的数据,先是品类,其次是第一次购买的产品类型,接着是第二次购买的产品类型,最后一列对应人数。

(注:这里第一次购买的产品前面加了“1-”,第二次购买加J = q v ~ - d . |了“2-”的区分标识。)

画图必备的nodes节点实现很简单,所有节点(品类、第一次购买、第二次购买)做去重汇总,对上面生成nodes代码稍作调整就可以:

手把手教你用 Python 绘制酷炫的桑基图

而linkes只接受source-traget-value的格式,得D m & | 1 I L ) L先对源数据进行格式调整,分别形成“品类-第一次购买-人数”,“第一次购买-第二次购买-人数”的样式,再统一汇总:

手把手教你用 Python 绘制酷炫的桑基图

规t h X )整汇总好之后,只需要复用上面的linkes代码:

手把手教你用 Python 绘制酷炫的桑基图

画图代码几乎没变,只是改了个{ 0 ~ n R = 3 ` q标题:

pE P u P Fic = ( Sankey .add(\'\', nodeQ M _ f z 3 E G ~s, linkes, linesty8 8 Hle_opt=op- C jts.LineStyleOpts(opacity = 0.3, cure ? / , a Nve = 0.5, color = \'source\'), label_opts=opts.Lab / y j n @ P ~ }belOpts(position = \'top\'), node_gap = 30, ) .set_global_opts(title_opts=opts.v W y + Z - f LTitleOpts(title = \'客户购买路径流转图e ! s c +\')))pic.render(\'te8 I ^ i 8 rst3.html\')

大; ? T F功告成,So easy!无论是多少层数据的流转,只要定义好nodeq U l O G u . Rs和li5 / k 9 L 7 g ? .nkesG K 6 B 6,就能以不变应万变。

手把手教你用 Python 绘制酷炫的桑基图

最后,通过上面的桑基图,我们能够非常直观的洞察到客户购买流转规律:

出于试错成本的考量,大部分客户第一次购买的是小规格狗粮。

第+ _ X一次购买小规格狗粮的客户,流失(第二次未购买)情况严重,且再次购买客户,更倾向于继续选择小规格狗粮尝试,1 M _ 6 } D q而不是信任性的购买大规格狗粮。

第一次购买大规格狗粮的客户,留存下来的客户已经建立起对品牌的信任感,再次购买大部分选择了大规格狗粮。

购买狗粮的客户第二次复A U Z g F l / D 8购鲜有尝试玩具的,而第一次购买玩具的客户,也并未建立起对品牌狗F = B | ` - G r 1 ( o

广东产业发展建设重点发布政策湖南崇义