数据可视化图形语法简史

原创
2018/02/09 10:19
阅读数 1.9W

数据可视化与制图理论

数据可视化的目的在于用图形化的手段,清晰有效地传达和沟通信息。常言道“一图胜千言”,原因就在于人能迅速获取和高效解读视觉信息。数据可视化的领域很广,历史也非常悠久。我们熟知的统计图表,譬如柱状图、折线图、饼图等,早在18世纪就已面世了。

18世纪 William Playfair 发明的几种常用统计图表

线、面

统计图表自 William Playfair 的时代开始,逐渐得到了越来越广泛的应用。也诞生了不少经典的案例,譬如南丁格尔19世纪50年代绘制的“玫瑰图”和法国工程师 Charles Joseph Minard 1861年绘制的“拿破仑东征”等等。

玫瑰图

拿破仑东征

不过直到20世纪下半叶,统计图表的制图理论和方法才得到了进一步的改革。法国制图师 Jacques Bertin 在研究了大量的图表案例之后,发表了可视化图表设计与制图的奠基之作《the Semiology of Graphics》。

封面

视觉元素

狭义的数据可视化就是把数据映射到一个二维平面上,通过人眼易于识别的视觉元素组合来表现数据。这本书为可视化提炼出几个最基础的视觉元素,为统计图表可视化工具的理论和实现奠定了基础。

图形语法

制图理论的完备,催生了越来越多的图表。计算机的普及和图形学的发展,也让统计图表得到进一步的丰富和发展。新的可视化图表层出不穷的同时,可视化图表绘制软件也越来越多,这时,在工程实现方面,有一个问题越来越突出:如何能以比较小的代价穷举尽可能多的图形?归根到底,就是如何表示一个可视化图表的问题。

Leland Wilkinson 在上世纪80年代开始开发 SYSTAT 的统计图形软件包时,也遇到了这个问题。最初的版本是枚举每一个能收集到的统计图形,最终代码量非常大,约 1.5M 左右。90年代初,他基于面向对象重构了这个项目,以一种树形结构管理图形元素,得到了更易扩展和动态的结果。这时软件包的大小下降到了 1M 以内。到了90年代末期,他和几个统计学家、计算机学家合作基于之前的工作开发了统计图形绘图工具 GPL。这个 Java 版本的软件代码量下降到了 0.5M 以下,并且沉淀出了一套稳定可靠的架构。

Leland Wilkinson 和《The Grammar of Graphics》

Leland Wilkinson

《The Grammar of Graphics》

《The Grammar of Graphics》就是 Wilkinson 在开发这套可视化软件的时候编写的,既有他对无数统计图表分析研究后的理论总结,也不乏实现图形语法的软件架构细节。至此,用一套语法描述任意图形的方法诞生了,编写基于图形语法的软件包有了理论依据和设计实践指导。

根据这本书的描述,统计图形的定义依靠以下几个基础语法:

声明 描述
DATA 从数据集生成视觉编码的数据操作
TRANS 视觉编码变换(譬如rank)
SCALE 度量变换(譬如log)
COORD 定义坐标系(譬如极坐标)
ELEMENT 图形(譬如点图)及其视觉属性(譬如color)
GUIDE 辅助元素(譬如legend)

生成一个统计图形的步骤如下图所示:

从数据到统计图形

from-data-to-graphic.png

那么,基于图形语法画一个饼图的过程是怎么样的?拿 JavaScript 版本的图形语法 G2 举例,代码如下:

G2 画饼图的过程

const data = [
  { k: '一', v: 40 }, 
  { k: '二', v: 21 }, 
  { k: '三', v: 17 },
  { k: '四', v: 13 }, 
  { k: '五', v: 9 }
]
const dv = new DataSet.View().source(data) // 载入数据
  .transform({ // 数据处理:统计每一个 key 对应数值 value 占总和的比例
    type: 'percent',
    field: 'v',
    dimension: 'k',
    as: 'percent'
  })
const chart = new G2.Chart({
  container: 'id' // 指定图表容器,可以是 DomNode,也可以是 id
})
chart.source(dv)                 // 载入数据
chart.axis(false)                // 不显示坐标轴
chart.coord('polar').transpose() // 坐标转换
chart.intervalStack()            // interval 类型的 element,做堆叠处理
  .position('1*percent')         // 位置映射
  .color('k')                    // 颜色映射
chart.render() // 渲染图表

和传统枚举图表类型的可视化工具相比,基于图形语法的可视化工具的特征是:生成每一个图形的过程就是组合不同的基础图形语法的过程。上述饼图的生成过程就经历了从原始数据 data 到数据转换、坐标轴转换、指定辅助元素、指定基础图形对象、度量转换、数据映射等过程。图形语法的灵活和强大之处就在于,我们只需要改动其中某一步的处理过程,就能得到完全不同的、全新的图表。譬如,上述代码只需改动坐标转换部分的语句,就能以下各种结果:

从左往右分别是:柱状图、条形图、牛眼图和饼图

直角坐标

直角坐标反转

极坐标

极坐标反转

.coord('rect')

.coord('rect')
.transpose()

.coord('polar')

.coord('polar')
.transpose()

而所有的语句都是可以改动和微调的,抽象出来的绘图过程每一个步骤都可以变换改动,从而产生无数种组合的图表。这正是图形语法的精髓之处,引用 ggplot2 作者的话来说,就是:

图形语法能让我们简洁地描述图形组件。这种语法能使我们超越命名图形(譬如散点图),更深入地理解统计图形的层次结构

通过图形语法,我们不仅能画出已知的几乎所有图表,更能组合创造出各式各样全新的图表来。

图形语法的开源实现

《The Grammar of Graphics》于1999年初版,2005年再版,至今已经有十多年历史。除了在各种商业系统(SPSS、Tableau等)中应用以外,开源社区也开始逐渐诞生各种版本。下面是几个比较典型的基于图形语法的开源实现。

ggplot2

ggplot2

ggplot2 是 R 语言社区最著名的可视化绘图包,2005年由 Hadley Wickham 创造。ggplot2 是目前开源社区图形语法特性实现最全面的软件,迄今已经成长为 R 社区乃至可视化业界最受欢迎的包之一。

Bokeh

Bokeh

Bokeh 是图形语法在 Python 技术栈下的实现。图形语法的实现是基于 Python 的,最终渲染是用 D3 在浏览器上绘图。其优势是可以借由 Python 获得大规模数据的处理能力,但也因为同时具备两个端(BS 架构),所以嵌入其他系统的成本相对较大。

Vega

vega.png

Vega 是华盛顿大学计算机学院数据交互实验室(IDL)开发的一套交互图形语法,定义了数据到图形的映射规则、常见的交互语法和常见的图形元素,用户可以自由使用 Vega 语法进行组合构建出各种各样的图表。其语法格式是 JSON,渲染引擎是 D3,一定程度上参考了《The Grammar of Graphics》,并且在其基础上进行了“用语法定义交互流程和行为”方面的探索。

AntV-G2

AntV-poster.jpg
G2 是一套基于可视化编码的图形语法,开源来自蚂蚁金服数据可视化团队,是蚂蚁金服数据可视化解决方案 AntV的重要组成部分。以数据驱动,具有高度的易用性和扩展性,用户无需关注各种繁琐的实现细节,一条语句即可构建出各种各样可交互的统计图表。G2 是目前 JavaScript 社区对《The Grammar of Graphics》还原度最高的实现,刚一开源就得到 Leland Wilkinson 本人的肯定。除实现“图形语法”部分以外,G2 还针对 JavaScript 技术栈在“数据驱动”和“交互”方面进行探索,愿景是实现一套“数据驱动的高交互可视化图形语法”。

未完待续

关于 G2,AntV 更多见 AntV-返璞归真幻化万千可视化表达

by 蚂蚁金服数据可视化团队,绝云 & 御术·林峰

展开阅读全文
打赏
2
9 收藏
分享

作者的其它热门文章

加载中
@Kener-林峰 ,你好,我想请教一个关于echarts的问题。我用echarts展示地图的时候,返回的数据出现了那种两个区域合并的情况(合并的两个区域比较远),roam只会在一个比较小的区域生效,有没有其他办法呀?
01/15 10:35
回复
举报
博主,里面的图都打不开。
请求的此类链接都没打开!https://lark.alipay.com/api/filetransfer?url=https%3A%2F%2Fprivate-alipayobjects.alipay.com%2Falipay-rmsdeploy-image%2Fskylark%2Fpng%2F18628bb5-6703-4ae3-80f1-37522e2fce55.png
2018/05/25 18:30
回复
举报
+1
2020/09/23 07:14
回复
举报
更多评论
打赏
3 评论
9 收藏
2
分享
返回顶部
顶部