作者 | 周志鹏
责编 | 郭 芮
最近,不止一次收到小伙伴的截图追问:
“这个图叫什么???”
“这个图真好看!!!怎么画啊?”
......
笔者本没有干货,问的人多了,也便有了干货。
此图姓桑名基,平素不喜露面。奈何天生丽质,偶有露面,必引众人围F % n F观。
时人有云:“桑基桑基,高贵美丽!”
桑基是何许图也?
据笔者不严谨的抽样提问统计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手把手绘制桑基图
动手之前,我们再次敲黑板,回顾桑基图组成要素j u 0的重点——节点、边和流量。
任何桑基图,无论展现形式如何夸张,色彩如何艳丽,动效如何炫酷,本质都逃不出上述3点。
只要我们定义好上述3个T g * 要素,Python的pyecharts库能够轻松实现桑基图的绘制O [ 2 s N ] Z | O。
这里我们用“当代青年熬夜原因分析”数据为例:
(数据来源:这个数据是笔者近两周卖炒粉时口头做的调研)
很规整的性别、熬夜原因、人数三列数据, B s 。
不! @ G u }过,要用pyecharts来画图,得入乡随俗,按照它定的规则来规整数据源。
首先是节点,这一步需要把所有涉及到的节点去重规整在一起。也就是要把性别一列的“男8 s 9 b 5 i @”、“女”和熬夜原因一列的“打游戏”、“加班”、“看剧”以列表内嵌套字典的形式去重汇总:
接着,定义边和流量,数据从哪里流向哪里,流量(值)H u y g o 2 P是多少,循环+字典依然可以轻松搞定:
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 optspic = (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回车下去,看看成果:
果然,男打游戏女看剧,加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\')
OK!不m ? J w ^过,k y Y 还有同学意犹未尽,这个是涉及到两层的流转,那如果三层,需要怎么画呢?
不慌,先导入(狗粮)数据:
这是某宠物品牌,3? Y e *月份主要产品购买路径(第一次和第二次)的数据,先是品类,其次2 o ~ Q C是第一次购买的产品类型,接着是第二次购买的产品类型,最后一列对应人数。
(注:这里第一次购买的产品前面加了“Q x Z ; N t1-”,第二次购买加了“2-”的区分标识。)
画图必备的nodes节点实现很简单,所有节点(品类、第一次购买、第二次购买)做去重汇总,对上面生成nodesV 3 d U代码稍作调整就可以:
而ll I 3 a A V ^inkes只接受source-traget-value的格式,得先对源数据进行格式调整,分别形成“品类-第一次购买-人数”,“第一次购买-第二次购买-人数”的样式,再统一汇总:
规整汇总好之后,只需要复用N - g $ 2 M s {上面的@ I Y 7 O :linkes代码:
画图代码几乎没变,| 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,就能以不变应万变。
最后,通过上面的桑基图,我们能够非常直观的洞察到客户购买流转规律:
出于试错成本的考量,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 $ =稿,版权归其所有。