跳至主要内容

账单可视化

· 阅读时间约 20 分钟

TLDR 本文探讨了数据可视化的本质定义和实践应用。通过对表格可视化价值的思考引入,阐述了可视化的核心是"通过视觉编码手段优化信息传递"。文章以账单可视化为具体案例,详细介绍了从设计思路到实现过程的完整流程,包括柱状图排序、动画设计、版面布局等多个技术要点。最终提出并实现了一个基于极坐标系的多层次可视化方案,通过内、中、外三环结构,有效展现了账单数据的多维度信息,并在实践中不断优化以提升可视化效果。

前言

刚入职一年时,被组中的同事问到这样一个问题:"你觉得表格算可视化吗?",从直觉上来说,当时的答案是否定的,在未深入了解前,我只能按照刻板印象给出答案:谈论起可视化,最起码也要包含柱折饼这些基础图表吧。谈起表格和可视化,我只能想到下面这种场景:

这个问题实际上伴随了我相当长的一段时间,因为它涉及一个很核心的概念:"什么是可视化?"。从中文的教育背景来说,找到它的答案很容易,因为我们总是在讨论"背景"、"意义"、"概念",所以很容易就可以从维基百科上获得以下概述:

信息

为了清晰有效地传递信息,数据可视化使用统计图形、图表、信息图表和其他工具。可以使用点、线或条对数字数据进行编码,以便在视觉上传达定量信息。有效的可视化可以帮助用户分析和推理数据和证据。它使复杂的数据更容易理解和使用。用户可能有特定的分析任务(如进行比较或理解因果关系),以及该任务要遵循的图形设计原则。表格通常用于用户查找特定的度量,而各种类型的图表用于显示一个或多个变量的数据中的模式或关系。

或者,我们可以问问大模型:

信息

数据可视化是将抽象的数据通过视觉元素(如图表、图形、颜色、形状等)进行编码,利用人类视觉系统的优势来快速识别模式、趋势和异常值。

这些随手翻阅的概念,实际上都没能回答上面提出的那个问题。随着我系统性地学习斯坦福的可视化课程、研读和复现前沿的论文、思考过往自己职业中的可视化场景,我对可视化的认知越来越深刻,最终我获得了我自己关于可视化的定义:

信息

通过视觉编码的手段,达到优化信息传递的目的,就是可视化。

那么表格算可视化吗? 答案当然是肯定的。

信息最基础的编码方式,在计算机中是二进制,在人类的自然语言表达中则是文本。假如没有表格,我们只能通过排列句来传递这类相似的信息,比如:"红色的苹果;黄色的香蕉;绿色的西瓜"。在数据数量较大时,排列句并不利于阅读,尤其是当形容词和名词可能并不等长时,在英语、阿拉伯语等语言中,这种失序感会进一步放大。

表格通过拆分文本,将名词和形容词分开,并采用二维行列式的方法,对文本信息进行编码,降低了人们的阅读成本。这一过程就是可视化,因为它通过视觉编码的手段,达到了优化信息传递的目的。

example
  • 中文

    红色的苹果;黄色的香蕉;紫色的葡萄;绿色的猕猴桃;橙色的橘子;粉色的火龙果;棕色的椰子;深红色的樱桃;青色的青柠;白色的火龙果。

  • 英文

    Red apple; yellow banana; purple grape; green kiwi; orange orange; pink dragon fruit; brown coconut; dark red cherry; cyan lime; white dragon fruit.

  • 中文表格
颜色水果
红色苹果
黄色香蕉
紫色葡萄
绿色猕猴桃
橙色橘子
粉色火龙果
棕色椰子
深红色樱桃
青色青柠
白色火龙果
  • 英文表格
ColorFruit
RedApple
YellowBanana
PurpleGrape
GreenKiwi
OrangeOrange
PinkDragon Fruit
BrownCoconut
Dark RedCherry
CyanLime
WhiteDragon Fruit

甚至于首字放大,实际上也是一种广义意义上的可视化。

问题

由于可视化的编码特性,使得在了解复杂问题或非直觉场景时,可视化能够帮助我们快速理解问题。尤其在统计学方面,由于数据、公式等元素都是非直觉的传达方式,且广泛存在于各行各业的问题场景中,所以数据可视化成为了一个更加被广泛认知的名词。

数据可视化有着天然的设计难度,从数据可视化的实现链路上看:

  • 数据清洗

    数据清洗要求设计者拥有基础的数据统计、数据处理知识;对常见的统计描述指标要有所了解,还需要掌握回归分析的基础知识。

  • 视觉编码

    视觉编码要求设计者拥有基础的审美能力,能够根据数据的特点选择合适的视觉通道,并进行合理的视觉编码。

  • 可视化设计

    可视化设计要求设计者根据具体的数据特性、具体的任务场景,找出合适的图表类型,设计符合直觉的交互方式,确保可视化设计可以达到预期的信息传递标准。

  • 可视化实现

    无论是绘制信息图,还是制作交互式图表,设计者都应该了解布局算法、几何特性等知识,才能确保视觉通道在相关的比例尺上正确映射。

从上面简单的描述看,很容易发现,这是一个跨学科的复合性场景,不仅需要逻辑处理,还需要创意表达。由于人体的脑功能侧化,左脑使用语言思考逻辑,右脑发挥创意及处理情感,大部分人群都难以做到两者兼备。

在现代企业的合作链路中,一般由多个角色来实现整个可视化流程,可能包括:数据分析师、可视化产品经理、可视化设计师、开发人员。通过这些角色的专业职能,来不断保证整个可视化流程的实施。

但是,实际上国内优秀的可视化人才非常稀少,仅在几个优秀的实验室中有定量产出,这意味着大部分场景下,都是由非专业人员借助已有的可视化工具来实施数据可视化设计和实现,比如 Tableau、Power BI、ECharts、Vega 等。在简单的场景下,借助已有的最佳实践指导和可视化工具,可以满足大部分的可视化需求,但是在一些高难度和复杂的场景下,非专业人员很难保证可视化设计可以达到预期的信息传递标准。

案例思考

柱图排列顺序

比如用这样一组数据来绘制柱状图:[['A',1],['B',3],['C',2],['D',4],['E',5]]

柱子应该如何排列?

如果 A、B 等元素是有序的,那么应该按照实际顺序排列,比如 A 和 B 可能是星期或者月份等。
如果 A、B 等元素无序,那么这里就有一个根据实际场景结合的空白编码

  1. 默认可能是根据数据升序或者降序排列
  2. 如果某个元素的文本长度过长,则可以将其转移到最左侧或者最右侧
  3. 也可以根据人体习惯的阅读顺序(根据地区不同),依据权重来决定元素的排列顺序
  4. 如果想突出最值,可以考虑将最值居中放置,使其在画面中更加突出

以上这些细枝末节的可视化设计思想,随着可视化场景愈加复杂,会变得更加重要,也会更加困难。比如在一些多图表的场景中,每个图表涉及多个维度,部分维度可能会在不同的图表中被复用,整体是一种交错的维恩图的映射。此时如果顺序是空白编码,且在不同的图表中顺序不一致,那么就会造成额外的理解成本,对信息传递造成额外负担。

柱图动画

同理,入场动画在大部分场景下也是一个空白编码,因为在视觉通道设计中,一般不会涉及动态效果。

比如下列的三种动画设计:

它们分别应用了不同的 animationDuration、animationEasing、animationDelay 等参数,来实现不同的动画效果。 如果仅从效果上看,这些动画都符合大众审美,因为它们使用了常见的动画参数,且没有任何割裂感。但是在具体的业务场景下,应该使用哪种呢?

版面问题

爱德华·塔夫特曾经提出墨水比(Data-Ink Ratio)概念,指出图表中用于表示数据信息的墨水与图表中总墨水的比值,这一思想指导我们在图表设计中应该尽量减少非数据相关的视觉元素。

同样的还有信息密度原则,即我们应该选择合适的尺寸来展示数据。但实际上这是一个常见的错误,思考下面的场景: 这是你的手机屏幕,你一定在银行或者理财 APP 中看到过类似的场景,柱状图占了整个屏幕 1/3 或 1/4 的版面,但是仅仅传递了 10 条以内的数据,信息密度过于稀疏,造成了严重的空间浪费。

大部分场景下,实际上并没有那么严格的可视分析需求,此时使用 Micro Chart 实际上会更加合适。理论上的最佳实践应该是渐进式的,即在用户聚焦前,使用 Micro Chart 展示数据,用户交互后,chart 尺寸逐渐展开,显示更多数据,此时还可以提供可视分析的专栏入口。

在特殊的问题场景下,我们甚至要结合使用一些异形图表、3D、动画等手段,来达到更好的 Storytelling 效果。

账单可视化

结合一个实际案例来说明这些可视化设计思想在实际场景中的应用。

支付宝、微信等应用提供了自己的账单分析功能,解决了一些基础的可视化需求。但是在做收支分析时,以我自身的需求出发,我更加关注的是自己周期性的消费习惯是否出现异常。

目前就业的互联网从业人员,消费非常符合周期规律:每月固定有薪资收入,每月固定消费可能包括房贷车贷、周末聚餐、购物休闲等。 所以在做收支分析时,我可能更加关注的是一段周期内,每月是否有较大金额的异常支出或收入,从而可以正确地认识到哪些是消费大头。

这里提一个金钱流的概念:单杯咖啡、单盒香烟、单个游戏的价值一般不会太高,但是人们很难认识到自己的消费频率,也就没办法正确认识到这一部分支出到底占据了消费的百分之多少,从而可能会造成过量消费。

初期的设计思路

  • 从上面提到的周期性看,整体的图表设计应该采用极坐标系
  • 结合支付宝内置的消费分类,也可以做一个大致的分类统计,这样对于自己的消费结构也可以有基础的认知
  • 统计上最好出现环比,这样可以查阅到具体分类的消费习惯变化
  • 每笔交易都应该是直观的,这样如果某一类消费出现异常,可以快速定位到具体是哪一笔交易

设计草图

由内、中、外三环构成:

  • 内环的极坐标柱状图分别统计各类别下的支出和收入,各占半环,并表示环比
  • 中环的折线图统计收入中各类别的消费趋势;散点图表示具体的收入交易
  • 外环的折线图统计支出中各类别的消费趋势;散点图表示具体的支出交易

中环代表收入,有内敛的含义;外环代表支出,有外放的含义。

需求细化与改进

  • 折线图应该采用堆叠,避免交错重叠的同时,还可以展现整体消费趋势
  • 内环极值应该采用整体周期的极值,否则无法感知到环比
  • 内环极值不应该包含数据的极值,尽管 ECharts 内部会进行取整,但如果数据极值也是整数,会出现难看的半圆,且有可能会干扰到相邻的元素
  • 内环的排布顺序应该按照从小到大的顺序,从圆心向外布局,这样可以彰显消费额大的频率,避免数据失真
  • 外环的折线图的 smooth 参数应该调整,否则会出现曲线交错
  • 内环的环比需要考虑增加和减少两种情况
  • 部分类别(如餐饮)的消费频率过高,在折线图上应该聚合,聚合单位为天
  • 内环末端的 label 位置很不好,几乎和图形重叠,这应该是 ECharts 内部的布局错误,暂且搁置
  • 消费区间分布存在严重不均,奢侈品/房产上的支出远高于餐饮/医药,需要提供额外的 filter 组件,使得用户可以关注到任意区间的分布
  • 环比仅考虑相邻月份之间的消费,如果某类别每隔几个月才出现一次,则不应该统计环比

最终效果

你可以在我的 GitHub 仓库访问到源码:https://github.com/kitee0325/bill-visual