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

作者 | 周志鹏

责编 | 郭 芮

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

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

“这个图叫什么???”

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

......

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

此图姓桑名基,平素不喜露面。奈何天生丽质,偶有露面,必引众人围F % n F观。

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

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

桑基是何许图也?

据笔者不严谨的抽样提问统计I K 1 U @,90%想学习桑基图的旁友,都是被她妖艳炫酷的外: t 1 H ! y表所吸引。

而桑基图真正代表了什么?和类似图表相比的独特性是什么?却几乎无人问津7 D m C 0 y

害!L h t N e r人真的是视觉动物!

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

桑基图(Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小,通常应用于能源、材料成分、金融等数据的可视化分T ; { t R析。因1898年Matthew Henry Phineas Riall Sankey绘制的X 1 H\"蒸汽机的能源效率图\m r k 0 _ ! G"而闻名,此后便以其名字命名为\"桑基图\"。 ] 2 F j ] .

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

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

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

  • 主要由节点、边和流量三要素构成,边越宽代表流量越大Q @ Z 3 M

  • 遵循守恒定律,无论怎么流动0 G S p + L Z n r,开端和末端数据总是一致的

文字太苍白,下面我们用Python来绘制一0 : | V s [ o个具体的实例。

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

Python手把手绘制桑基图

动手之前,我们再次敲黑板,回顾桑基图组成要素j u 0的重点——节点、边和流量。

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

只要我们定义好上述3个T g * 要素,Python的pyecharts库能够轻松实现桑基图的绘制O [ 2 s N ] Z | O

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

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

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

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

! @ G u }过,要用pyecharts来画图,得入乡随俗,按照它定的规则来规整数据源。

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

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

接着,定义边和流量,数据从哪里流向哪里,流量(值)H u y g o 2 P是多少,循环+字典依然可以轻松搞定:

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

source-target-value的m ! y J . l字典格式,很清_ 2 H G ;晰的描述了数据的流转情况。

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

from pyecharts.charts import Sankeh n ] / Gyfrom pyecharI ( 8 e ts import option!  5 P ys as opts
pic = ( Sankey .add(\'\', #图例名称 nodes, #传入节点数据 linkes, #N b B O 8 l传入边和流量数据 #设置透明度、弯曲度、颜色 linestyle_opt=opts.LineStyleOpts(opacity = 0.3, curve = 0.5, color = \"sourn D ; Jce\"), #标签显示位置 label_opts=opts.LabelOpts(position=\"right\"), #节点之前的距离 node_gap = 30, ) .sed _ ! Z ? 2t_global_opts(tC j / U $ K L &itle_opts=opts.TitleOpts(title = \'熬夜原因桑基图\'))B l 6 A t)
pO & ? ? ) C uic.rendeG F ? tr(\'test.html\')

一个} 6 5 F H回车下去,看看成果:

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

果然,男打游戏女看剧,加h F B b Y班熬夜是儿戏。

如果想要垂直显示,只需O - Z S要在add函数里面加一个orient=\"vertical\"就好A T f o J 3 c T

pic = ( Sankey .add(\'\', nodes, linkes, linestyle_opt} b ( t , , k=opts.LineStyleOo G = ; $ { K tpts(opacity = 0.3, curve = 0.5, color = \"source\"), label_1 3 S ropts=opts.LabelOpts(position=\"top\")M  6 G B &, node_gap = 30, orij C ( * [ P 3 T ^ent=\"vertical\", #更改的是这里 ) .set_gls ) j Fobal_opts(title_opts=optj [ 1s.TitleOpts(title = \'熬夜原{ O R因细分桑基图l Q @ 1 M 4\')))
pic.render(\'tesh K / j ` ) Gt2.html\')

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

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

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

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

这是某宠物品牌,3? Y e *月份主要产品购买路径(第一次和第二次)的数据,先是品类,其次2 o ~ Q C是第一次购买的产品类型,接着是第二次购买的产品类型,最后一列对应人数。

(注:这里第一次购买的产品前面加了“Q x Z ; N t1-”,第二次购买加了“2-”的区分标识。)

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

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

而ll I 3 a A V ^inkes只接受source-traget-value的格式,得先对源数据进行格式调整,分别形成“品类-第一次购买-人数”,“第一次购买-第二次购买-人数”的样式,再统一汇总:

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

规整汇总好之后,只需要复用N - g $ 2 M s {上面的@ I Y 7 O :linkes代码:

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

画图代码几乎没变,| Y e只是改了个标题:

pic = ( SanA L @ M /key .add(\'4 D J n\', nodes, linkes,Y : + linestl 5 O h k 6yle_opt=opts.LineStyleOpts(opaciM C u s ! : !ty = 0.3, curve = 0.5, color = \'source\'), label_opts=opts.LabelOpts(position = \'top\'), node_gap = 30, ) .set_& w B F d p ( Bglobal_opts(title_opts=opts.x % ^ _ l v w S ?TitleOpts(title = \'客户购买路径流转图\')))pic.render(\'test3.html\')

大功告成,So easy!无论是多少层数据的流转,只要定义好nodes和linkes,就能以不变应万变。

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

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

出于试错成本的考量,S ( ( H { Y a = q大部分客户第一次购买的是小规格狗粮。

第一次购买小规格狗粮的客户,流失(第二次未购买)情况严重,且再次购买客户,更倾向于继续选择f c x 5 h , z小规格狗粮尝试,而不是信任性的购买大规格狗粮。

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

购买狗粮的客户第二次复购鲜有尝试玩具的,而第一次购买玩具的客户,也并未建立起对品牌狗粮的兴y z & 4 s D D趣。

原本死板的数据,在桑基的装扮之下,变得楚楚动人。

A m q G e s ?明:本文为作者投9 $ =稿,版权归其所有。

上一篇

新能源汽车动力电池报废量持续增长,推动动力回收行业快速发展

下一篇

半导体行业景气度前低后高 通富微电2019年下半年业绩“翻身”全年实现盈利

你也可能喜欢

  • 暂无相关文章!

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片
返回顶部