本节书摘来自异步社区《R绘图系统(第2版)》一书中的第1章,第1.2节,作者【新西兰】Paul Murrell,更多章节内容可以访问云栖社区“异步社区”公众号查看
1.2 R绘图系统的结构
这一节简要阐述了R 绘图函数库中的函数是如何组织的,以使用户能够了解怎样开始寻找一个特定的函数。
在R绘图工具库中占据核心地位的是grDevices包,该包同时也被称为绘图引擎。grDevices包提供了一系列R中的基本绘图函数,如选择颜色和字体以及选择绘图输出格式。尽管几乎所有的R绘图应用都使用了grDevices包,这其中绝大部分只需要通过学习一些基本知识即可掌握,所以关于该包中绘图函数的细节被安排在本书第3部分介绍。
在绘图引擎的基础上直接搭建了两个包:graphics包和grid包。这两个包代表着两个巨大的不相容的绘图系统,并将R的绘图功能从主体上分割成了两个不同的部分。
graphics包,也被称为传统绘图系统,提供了创建一系列丰富的通用图形所用到的完整函数集,以及供用户在自定义图中能够控制到非常具体的细节所需要的绘图函数。这些内容在本书第1部分具体介绍。
grid 包则提供了一系列不同的基本绘图工具。它并没有提供绘制完整图形的函数,所以通常并不直接用于绘制统计图形。相反,人们广泛使用基于grid之上所开发的绘图包中的函数,特别是其中的lattice 包和ggplot2包。这3个包,构建起了R grid绘图系统中的主体,关于这3个包的介绍安排在本书的第2部分。
此外,还有许多其他的绘图函数包是基于graphics包或者grid包的。例如,maps 包提供了在传统绘图系统中绘制地图所需的函数,pixmap包提供了可以嵌入外部光栅图像,特别是graphics包内部绘制的图形所需要的函数,而grImport包则提供了能够包含外部矢量图像,特别是通过grid绘图系统所绘制的图形所用到的函数。图1.14展示了从这些绘图包中选取的一小部分。本书的第4部分将广泛选取R的一些扩展包给予介绍。
有一些包则相当程度的独立于R中主要的绘图工具库。这些包提供了R 与第三方绘图系统的接口,例如用于绘制复杂三维图形的OpenGL图形库(rgl 包),以及绘制动态交互图形系统的图形库(rggobi 和 iplots 包)。这些包将在本书第四部分作基本介绍。
最后,还有一些为R提供了额外绘图设备的函数包。这些包使得R 图形输出能够嵌入到其他系统,例如,tikzDevice包可以绘制嵌入到LaTex文件的图形,JavaGD 包提供了在Java应用内实现R图形输出的功能。在本书第3部分会提及这些包。
1.2.1 绘图函数的类型
R绘图系统与绘图程序包可以分成两个主要类型:用于绘制完整图形的高级函数和在已经存在的图形上添加额外图形的低级函数。
传统绘图系统以及在其之上构建的绘图程序包,提供了当前R中可用高级绘图函数的主体。最重要的例外是lattice包(见第4章)和ggplot2包(见第5章),这两个包提供了基于grid绘图系统的完整绘图函数。同时,传统绘图系统和grid 绘图系统也提供了许多低级绘图函数。
大多数绘图包中的函数都用来绘制完整的图形,并且通常用于提供针对某种特定类型分析或者专门领域研究所需的绘图功能。例如:在hexbin包中提供了用于海量数据可视化的六边形面元化绘图功能(见12.5节);maps包提供了地理数据可视化的绘图函数(见14.1.1小节);scatterplot3d提供了绘制多种三维图形的绘图功能(见16.5节)。如果读者有绘制某种特定类型图形的需要,很可能已经有人编写了实现这类功能的函数。例如,在R-help邮件列表中经常有人询问如何在散点图或者条形图中增加误差条,实现该功能的方法有很多种,例如,使用传统的arrows()函数,使用gplots包中的plotCI()函数或者使用Hmic函数包中的errbar()函数。R提供了一些用来连接R主页站点的搜索工具以帮助用户寻找为实现某个特定目的所需要的专业函数。在sos程序包中,就通过函数findFn() 提供了一个友好的网络接口。
图1.14 R图形系统的结构。深灰色背景的包构成了图形系统的核心。本书第1部分介绍了graphics包,第2部分会介绍grid、lattice和ggplot2包,第3部分会介绍grDeivces包。浅灰色背景的包是对核心系统作扩展的示例,会在第4部分介绍。有一些包提供了独立的图形系统,我们会在几个代表性的包中详细介绍这些图形系统,它们和核心图形包没有关系。
1.2.2 传统绘图系统与grid绘图系统
R中存在着两个不同的绘图系统,传统绘图系统与grid绘图系统,这就带来了一个问题,在什么时侯选用什么样的绘图系统。
对于某些以通过简单函数调用来绘制完整图形为目的的用户来说,如何选择绘图系统大多数时候依赖于需要绘制何种类型的图形。如果没有在现有图形上添加更多图形的需要,对绘图系统的选择很大程度上是彼此不相干的。
如果有在现有图形上添加更多图形的需要,用户则需要知道该用何种绘图系统绘制初始图形。通常,应该使用同一个绘图系统添加额外的图形(尽管在第19章中介绍的gridBase程序包中,提供了一种绕开这种限制的方法)。
对一系列通用标准图形来说,可以通过使用lattice、ggplot2和graphics包提供的函数来绘制3种不同样式的该类图形。作为通用准则,lattice和ggplot2包所默认的样式通常被优先使用,因为它们都是根据人们的认知规律而开发设计从而使得图形能够更好地传递信息。
对于多元数据集的可视化,lattice和ggplot2包也提供了更多复杂的支持,例如向一个简单的两个连续变量的散点图中添加内容,可以通过对数据内不同子集使用不同线段或者使用不同的图形符号来表示,或者对不同的子集绘制单独图形的方式来实现。
当然,使用lattice和ggplot2包中的高级特性的代价是,用户需要付出很大的努力学习并熟悉这些包所对应的知识体系。对于lattice包,用户需要专门学习如何显式的定制默认样式,而对于 ggplot2 ,则需要一段时间去适应 ggplot2 的设计理念,尽管掌握了这种理念就可以设计出更多一致且强大的图形样式。
总之,关于如何选择绘图系统,用户可能会从快速上手的角度选择传统绘图系统,但是从长远看,lattice和ggplot2包能够提供更多有效并且复杂的选项。
对于更多专项绘图,例如绘制地图或者节点-边图,选择是根据那个程序包提供相关绘图函数决定的(见本书第4部分的相关章节)。
一个不同的问题是当绘制那些没有现成函数可以用的图形时,需要借助低级函数。在这种情况下,相比于传统绘图系统的低级函数,grid绘图系统提供了更加广泛的可用选择,代价是需要深入学习一些概念。
如果用户的目的是创造新的绘图函数供其他人使用,grid绘图系统也提供了比传统绘图系统更好的支持,使用户更容易绘制混合了各类图形的复杂图形。
最后需要考虑的是速度。没有任何绘图系统能够盲目地被描述为快速的,但是基于grid的绘图系统速度明显要慢于传统绘图系统,并且这些缺点在某些应用中会特别明显。
章节总结
R 绘图系统由一个核心绘图引擎和两个低级绘图系统(传统绘图系统和grid绘图系统)构成。传统绘图系统包含了很多高级函数用于绘制完整图形。搭建于grid绘图系统之上的lattice包和 ggplot2包也提供了高级绘图函数库。许多扩展程序包为这个两个绘图系统提供了更多的绘图工具,这意味着用户有可能利用R创造出许多丰富多彩的图形和图像。