需求背景
工程场景是这样的:我需要展现不同类别在一段日期内的多个指标的变化趋势图。大体思路是这样:对每个指标画一张图,在每张图上画出多条曲线,每条曲线对应一个类别在此日期内的指标数据。
由于处理数据相关的代码使用的 Python,所以我先尝试了使用 Python 的 matplotlib 这个画图工具包。经过我的几经调试,将不同量级的曲线置于不同 panel,最终能画出的最好图形仅仅如下:
No.1 图
显然这是很难拿出手向团队展示的,于是我转向了较熟悉的R的 ggplot2 画图包。稍费了些波折,调试出了下面这张不错的趋势图:
No.2 图
可是 No.1 图的问题在于最下面的三根曲线挨的太近。曲线挨的太近,是因为两条曲线的y值差异相比y轴的表示范围太小,一个可行的方案就是将挨的太近的曲线新放到一个 panel 或称分面里。而实际上,该图只是指标一的趋势图,还有其他指标的图,在其他趋势图中,并非正好还是这三条曲线挨的太近,也许就换成另外两条或者多条。所以我索性将每个类别对应的曲线都放到一个 panel 里,就画出了 No.2 图。
No.3 图
No.2 图中没有让y轴按照当前 panel 曲线的y值大小自适应修改其表示范围,结果就是曲线根本看不出波动,因为y轴的 range 还是0~2500,而 panel 高度缩小到了1/7。我认为一些波动大曲线的 panel 应该用更高的 height 来显示,所以除了让y轴的 range 自适应的同时,也让 panel 的 height 自适应,结果又画出了下面这张图。
No.4 图
No.3 图的问题也显而易见,「好」的 panel 显示够好,「差」的 panel 显示够差。因为y值小的曲线即便相对波动交大,但绝对y轴 range 还是太小,所以就被自适应为了 height 很小的 panel。最后,我锁定了 panel 的 height,只让y轴 range 自适应,画出这张我最满意的趋势图。
技术之外的思考
结束了画图,来思考一个问题:如果第一张图像中的不存在曲线挨的太近的情况,是不是就可以认为它才是画出来的最好的图像呢?
我起初认为:毫无疑问是的。因为 No.1 图中曲线都在一个 panel 里,除了波动大的曲线幅度显示能足够充分外,不同曲线之间也可以通过上下位置直接看出指标的差异。这是我画图之前脑海里就设想的图像。可是这只是我完全没有走出技术之外的认识,从技术之外去思考,No.1 图的问题可不少:
对于曲线指标范围绝对值小的曲线而言,会很难在视觉上显示显著的波动。而我只看到图中曲线有的显著波动,有的近似平行,漂亮地安放在图中真完美。而展示出这种曲线的波动趋势意义同样重大,他们并非是为了存在于图中衬托其他曲线。我没去考虑数据特点的差异,我只想着使用这些数据画出看上去更「漂亮」的图。
No.1 图依靠曲线颜色区分不同的类别,这似乎很会运用元素转换,并使得图像更干净。可是这其实不如 No.4 图中每个 panel 右侧直接显示类别名称清晰和实用,因为让看这些趋势图的人去对着颜色寻找对应的曲线绝对是愚蠢的,他们希望趋势图能让他们读数据更快,现在居然让他们每次瞪着眼睛将颜色和类别对上,还不如让他们直接去读表格数据。
像 No.1 图那样使一些曲线在视觉上显著波动并非是好事,因为这种波动是跟 panel 的 height 有直接关系的,height 越高,曲线看上去波动就越大,这种波动很可能导致数据变化幅度很大的误导,而数据真正的变化幅度还要从其对于的y值差异去看。所以根本不应该为了追求曲线在视觉上的显著波动,而让曲线的 panel 尽可能高。
No.1 图能通过曲线位置高低来观察不同类别的指标差异是相比于 No.4 图仅存的优势了,这一度让我很伤心,因为终于找到很好的 No.4 图,但是却带着缺陷。可是好好去思考我要展示的数据的特点,就会发现,类别间的指标差异是稳定存在的,这周的趋势图,下周的趋势图,下下周的趋势图,类别指标的大小顺序是很稳定的,所以在这种情况下,No.1 图只不过多展示一个无需看图也知道的特征。最后我十分安心地选择了 No.4 图。
小结
要想画出最合适的趋势图,最大的付出不在于学习到 cool 技术的各种玩法,而在于用心去思考所要展现的数据的特点和看图人真正的需求,这技术之外的思考才是最值得的。可是似乎很多人都只关心到了技术之内,比如 mac 是比 windows 更好的技术,看到很多文章介绍 mac 的特性,新玩法和好软件,我不知道这价值何在,希望也能看到更多技术上的介绍是来自技术之外的思考。