在我的《Tableau高级图表进阶》课程群里,我会经常跟同学们讨论Tableau绘图的问题,因为我希望我的课程不仅仅是教授技巧而是传授思路,授人以渔才是我课程的初衷。
前些天我制作了一个梯形漏斗图(下图基础-梯形漏斗图),建议大家思考一下改进。winnie同学与我进行了大量的讨论,最终在我的提一下,由她主笔完成了这篇文章。
本文从条形漏斗图→基础梯形漏斗图→进阶梯形漏斗图,循序渐进地讲述漏斗图的实现方法,同时也把她思考的过程记录了下来。
也希望更多的愿意思考的同学参与进来,我们共同研究Tableau。
条形漏斗图
数据源
层次 留存率
层1 100%
层2 80%
层3 50%
层4 20%
原理解析
拖拽并复制[留存率],生成两个条形图,设置两个条形图坐标轴区间大小一致,其中一个条形图的坐标轴设置为倒序以达到对称的镜像效果,双轴后形成漏斗效果。
实现步骤
- 将[层次]拖到行,[留存率]拖到列,设置[留存率]的度量计算方式为平均值
- 按住ctrl,将行中的[层次]拖到标记的颜色和标签,列中的平均值[留存率]拖到标记的标签,并设置标签的对齐方式为左对齐
- 按住ctrl,拖动列中的平均值[留存率],复制一个平均值[留存率]的轴
- 设置第一个平均值[留存率]的坐标轴范围,固定为区间[-1,1]
- 设置第二个平均值[留存率]的坐标轴范围,固定为区间[-1,1],勾选“倒序”
第4、5两步将坐标轴大小固定在[-1,1]区间,是为了让两个轴的图形显示为一样大小,第二个轴倒序的目的是为了让第二个轴的条形图和第一个轴的条形图形成镜像的视觉效果。
- 右键第二个平均值[留存率],点击双轴,隐藏标题并去除相关的线,即可生成<条形漏斗图>
条形漏斗图实现起来比较简单,主要知识点在于运用好坐标轴,对应日常工作中已经足够。
基础梯形漏斗图
如果希望看起来更像漏斗,则涉及到高级图形技巧和知识点的掌握和运用,下面描述基础梯形漏斗图的实现原理和实现步骤。
数据源补充
我们在上面的数据源基础上补充一下数据
path
1
2
3
4
将两张表格做内部联接,可以分别新建一个名字为1的字段,作为连接依据。
原理解析
实现步骤
创建计算字段
- 高度= if [Path] = 1 or [Path] = 4 then 0 ELSE 1 END
设置点1和点4的纵坐标为0,横坐标为1
- 宽度-基础=
IF min([Path]) = 1 then -LOOKUP(avg([留存率]),1)
ELSEIF min([Path]) = 2 then -avg([留存率])
ELSEIF min([Path]) = 3 then avg([留存率])
ELSEIF min([Path]) = 4 then LOOKUP(avg([留存率]),1)
END
1、lookup():因为漏斗朝下,要lookup下一层[留存率],因此表计算方向为[层次],分区为[path]
2、min():涉及到表计算函数loookup(),因此[path]前增加了min函数以达到聚合效果,此处使用min、max、avg均可,看个人心情~
- 将[层次]字段拖到行,[高度]字段拖到行,设置[高度]聚合方式为平均值;
- 将[宽度-基础]字段拖到列,设置[宽度-基础]字段聚合方式为平均值
- 设置[宽度-基础]字段的表计算依据为[层次]
- 设置标记类型为多边形
这里并没有生成我们想要的漏斗图,并且图形右下角提示有“2个null”;双击“2个null”提示[宽度-基础]字段具有2个null值,为了一探究竟,我们采用交叉表进行分析:发现由于分区结束,层4的点1和点4无法lookup()到对象,因此返回null:
null解决方案1(临时对策):点击“2个null”,选择复选框“在默认位置显示数据”,即可生成右侧图形,原理说明如下图:
null解决方案2(永久对策):修改[宽度-基础]字段,在lookup()函数前增加zn()函数:如果lookup结果为null,返回0值;
IF min([Path]) = 1 then -zn(LOOKUP(avg([留存率]),1))
ELSEIF min([Path]) = 2 then -avg([留存率])
ELSEIF min([Path]) = 3 then avg([留存率])
ELSEIF min([Path]) = 4 then zn(LOOKUP(avg([留存率]),1))
END
下面以null解决方案2为基础,继续进行
- 将[层次]拖到颜色;设置[高度]坐标轴,将坐标轴区间固定在[0,1],各个分区之间便没有留白了,漏斗的形状已生成
- 复制[宽度-基础]字段,将标记“多边形”修改为文本,去掉 [Path]字段,增加标签[留存率],设置[留存率]聚合方式为平均值,双轴即可生成漏斗图
Tips: 此时,有强迫症的你一定想让标签居中,但是,怎么拖动或设置标签的位置,它都一动不动!
原因解析:以第一个矩形为例,标签100%对应的宽度坐标为-0.8,因此无法拖动,为了解决该问题,需要进一步优化[宽度-基础]字段,让[宽度-基础]的值为0以实现居中
解决方案:在[宽度-基础]计算公式中增加IF count([Path])>1 then 0,这样[宽度-基础]的值就等于0了 (本文数据源count([Path]) = 4,读者自行通过交叉表观察)
IF count([Path])>1 then 0
ELSEIF min([Path]) = 1 then -zn(LOOKUP(avg([留存率]),1))
ELSEIF min([Path]) = 2 then -avg([留存率])
ELSEIF min([Path]) = 3 then avg([留存率])
ELSEIF min([Path]) = 4 then zn(LOOKUP(avg([留存率]),1))
END
- 为了更快捷调整标签位置(编者太懒),将第二个[宽度-基础]轴的标记类型改为圆,设置颜色透明度为0%,边界设置为无;双轴,去掉边界线条;
完整的基础漏斗图就做完了!
细心的同学会发现,这个漏斗的底部是尖角。下面我们加大难度,讲讲怎么把底部从尖角变成平底。
进阶漏斗图的制作
原理解析
实现过程
利用基础漏斗图的源数据,进行宽度字段的修改。
- 高度=if [Path] = 1 or [Path] = 4 then 0 ELSE 1 END
此字段无变化
- 层次=INDEX()
新增字段,用于计算[宽度-进阶]
- 宽度-进阶=
IF COUNTD([Path])>1 then 0
ELSEIF min([Path]) = 2 then -avg([留存率])
ELSEIF min([Path]) = 3 then avg([留存率])
ELSEIF min([Path]) = 1 and [层次 index] = WINDOW_MAX([层次 index]) then -avg([留存率])
ELSEIF min([Path]) = 1 then zn(-LOOKUP(avg([留存率]),1))
ELSEIF min([Path]) = 4 and [层次 index] = WINDOW_MAX([层次 index]) then avg([留存率])
ELSEIF min([Path]) = 4 then zn(LOOKUP(avg([留存率]),1))
END
在[宽度-基础]字段的基础上,在1和4两个点上,分别增加了两个判断条件,起作用只是为了生成最后一层(层4)的点1和点4的横坐标。
- 将[层次]字段拖到行,[高度]字段拖到行,设置[高度]聚合方式为平均值;
- 将[宽度-进阶]字段拖到列,设置[宽度-进阶]字段聚合方式为平均值
- 设置[宽度-进阶]字段的表计算依据为[层次]
- 设置标记类型为多边形
- 设置[宽度-进阶]字段表计算的嵌套计算依据,包含 [层次 index]和[宽度-进阶]两个字段,详见下图红框:
- 复制一个[宽度-进阶]字段,将第二个[宽度-进阶]轴的标记类型改为圆,设置颜色透明度为0%,边界设置为无;双轴,去掉边界线条;
进阶漏斗就做成啦。
结语:从条形图漏斗→基础漏斗→进阶漏斗,编者在整个制作过程种,“故意”设置了一些路障并修正方法,希望读者(初学者)通过涉及的知识点,提高对Tableau原理的理解。
第四种方法
上面的方法基本已经够用,鉴于篇幅限制,仅以前3种为例进行了介绍,第4种制作漏斗图的方法请参阅Winnie的public;
4种漏斗public:
https://public.tableau.com/profile/.30391162#!/vizhome/4_16147862603070/1-3?publish=yes
关于Tableau中如何用多边形绘制图表的原理,大家可以参考我的Tableau高级图表进阶课程中的第三部分第1课如何画一个简单的圆。
此篇文章已发布到我的公众号: saodisir,有兴趣也可关注一下