R语言数据可视化之美:专业图表绘制指南(增强版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.6 ggplot2图形语法

ggplot2是一个功能强大且灵活的R包,由Hadley Wickham编写,它可以生成优雅而实用的图形。ggplot2中的gg表示图形语法(grammar of graphic),这是一个通过使用“语法”来绘图的图形概念。ggplot2主张模块间的协调与分工,整个ggplot2的语法框架如图1-6-1所示,主要包括数据绘图部分与美化细节部分。R ggplot2图形语法的主要特点如下所示。

(1)采用图层的设计方式,有利于结构化思维实现数据可视化。有明确的起始(ggplot()开始)与终止,图层之间的叠加是靠“+”实现的,越往后,其图层越在上方。通常一条geom_×××()函数或stat_×××()函数可以绘制一个图层。

(2)将表征数据和图形细节分开,能快速将图形表现出来,使创造性的绘图更加容易实现。而且通过stat_×××()函数将常见的统计变换融入绘图中。

(3)图形美观,扩展包(extension package)丰富,有专门调整颜色(color)、字体(font)和主题(theme)等辅助包。可以帮助用户快读定制个性化的图表。

图1-6-1 ggplot2语法框架

ggplot2的绘图基本语法结构如图1-6-2所示。其中所需的图表输入信息如下所示。

(1)ggplot():底层绘图函数。DATA为数据集,主要是数据框(data.frame)格式的数据集;MAPPINGS变量的视觉通道映射,用来表示变量xy,还可以用来控制颜色(color)、大小(size)或形状(shape)等视觉通道;STAT表示统计变换,与stat_×××()相对应,默认为"identity"(无数据变换); POSITION表示绘图数据系列的位置调整,默认为"identity"(无位置调整),关于POSITION的具体内容可见第3章3.1节。

(2)geom_×××()| stat_×××():几何图层或统计变换,比如常见的geom_point()(散点图)、geom_bar()(柱形图)、geom_histogram()(统计直方图)、geom_ boxplot()(箱形图)、geom_line()(折线图)等。我们通常使用geom_×××()函数就可以绘制大部分图表,有时候通过设定stat参数可以先实现统计变换。

可选的图表输入信息包括如下5个部分,主要是实现图表的美化与变换等。

(1)scale_×××():度量调整,调整具体的度量,包括颜色(color)、大小(size)或形状(shape)等,跟MAPPINGS的映射变量相对应;

(2)coord_×××():坐标变换,默认为笛卡儿坐标系,还包括极坐标系、地理空间坐标系等;

(3)facet_×××():分面系统,将某个变量进行分面变换,包括按行、列和网格等形式分面绘图,这部分内容具体可见第8章8.2节。

(4)guides():图例调整,主要包括连续型和离散型两种类型的图例。

(5)theme():主题设定,主要用于调整图表的细节,包括图表背景颜色、网格线的间隔与颜色等。

图1-6-2 ggplot2绘图的基本语法结构

1.6.1 geom_xxx()与stat_xxx()

1.geom_xxx():几何对象函数

R中的ggplot2包包含几十种不同的几何对象函数geom_×××(),以及统计变换函数stat_×××()。通常,我们主要使用几何对象函数geom_×××(),只有当绘制图表涉及统计变换时,才会使用统计变换函数stat_×××(),比如绘制带误差线的均值散点图或柱形图等。使用geom_point()函数绘制的散点图与气泡图如图1-6-3所示,ggplot2默认使用直角坐标系。

图1-6-3 geom_point()函数的绘制过程

根据函数输入的变量总数与数据类型(连续型或离散型),我们可以将大部分函数大致分成3个大类,6个小类,如表1-6-1所示,但是有两类函数没有囊括在此表中。

(1)图元(graphical primitive)系列函数:geom_curve()、geom_path()、geom_polygon()、geom_rect()、geom_ribbon()、geom_linerange()、geom_abline()、geom_hline()、geom_vline()、geom_segment()、geom_spoke(),这些函数主要是用于绘制基本的图表元素,比如矩形方块、多边形、线段等,可以供用户创造新的图表类型。

(2)误差(error)展示函数:geom_crossbar()、geom_errorbar()、geom_errorbarh、geom_pointrange()可以分别绘制误差框、竖直误差线、水平误差线、带误差棒的均值点。但是,这些函数需要先设置统计变换参数,才能自动根据数据计算得到均值与标准差,再使用其绘制误差信息。

每个ggplot2函数的具体参数信息可以查看RStudio的“help”界面或者ggplot2的官方手册ggplot2的官方手册:https://ggplot2.tidyverse.org/reference/index.html

表1-6-1 ggplot2函数的分类

2.stat_xxx():统计变换函数

统计(stat)变换函数在数据被绘制出来之前对数据进行聚合和其他计算。stat_×××()确定了数据的计算方法。不同方法的计算会产生不同的结果,所以一个stat()函数必须与一个geom()函数对应才能进行数据的计算,如图1-6-4所示。在某些特殊类型的统计图形制作过程中(比如柱形图、直方图、平滑曲线图、概率密度曲线、箱形图等),数据对象在向几何对象的视觉信号映射过程中,会做特殊转换,也称统计变换过程。为了让作图者更好地聚焦于统计变换过程,将该图层以同效果的stat_×××()命名可以很好地达到聚焦注意力的作用。

图1-6-4 stat_count()函数的绘制过程

我们可以将geom_×××(几何对象)和stat_×××(统计变换)都视作图层。大多是由成对出现的geom_×××()和stat_×××()函数完成的,绘图效果也很相似,但并非相同。每一个图层都包含一个几何对象和一个统计变换,也即每一个以geom_×××开头的几何对象都含有一个stat参数,同时每一个以stata_×××开头的几何对象都拥有一个geom参数。但是为什么要分开命名呢,难道不是多此一举吗?

· 以stat_×××()开头的图层,在制作这些特殊的统计图形时,我们无须设定统计变换参数(因为函数开头名称已经声明),但需指定集合对象名称图表类型geom,就可以绘制与之对应的统计类型图表。这样需要变换geom()函数,就可以根据统计变换结果绘制不同的图表,可以使得作图过程更加侧重统计变换过程。

· 以geom_×××()开头的图层,更加侧重图表类型的绘制,而通过修改统计变换参数,也可以实现绘图前数据的统计变换,比如绘制均值散点,下面语句(a1)和语句(b1)实现的效果是一样的,语句(a1)是使用指定geom="point"(散点)的stat_summary()语句,而语句(b1)是使用指定stat="summary"的geom_point()语句。

       (a1)ggplot(mydata, aes(Class, Value, fill = Class))+
                stat_summary(fun.y="mean", fun.args = list(mult=1), geom="point", color = "white", size = 4)
       (b1)ggplot(mydata, aes(Class, Value, fill = Class))+
        geom_point(stat="summary", fun.y="mean", fun.args = list(mult=1), color = "white", size = 4)

绘制带误差线的散点图,下面语句(a2)和语句(b2)实现的效果也是一样的,语句(a2)是使用指定geom="pointrange"(带误差线的散点)的stat_summary()语句,语句(b2)是使用stat="summary"的geom_pointrange()语句。

       (a2)ggplot(mydata, aes(Class, Value, fill = Class))+
                stat_summary(fun.data="mean_sdl", fun.args = list(mult=1), geom="pointrange", color = "black", size = 1.2)
       (b2)ggplot(mydata, aes(Class, Value, fill = Class))+
        geom_pointrange(stat="summary", fun.data="mean_sdl", fun.args = list(mult=1), color = "black", size = 1.2)

其中,fun.data表示指定完整的汇总函数,输入数字向量,输出数据框,常见4种为: mean_cl_boot、mean_cl_normal、mean_sdl、median_hilow。fun.y表示指定对y的汇总函数,同样是输入数字向量,返回单个数字median或mean等,这里的y通常会被分组,汇总后是每组返回1个数字。

当绘制的图表不涉及统计变换时,我们可以直接使用geom_×××()函数,也无须设定stat参数,因为会默认stat="identity"(无数据变换)。只有涉及统计变换的处理时,才需要使用stat参数,或者直接使用stat_×××()以强调数据的统计变换。

1.6.2 视觉通道映射

R语言可用作变量的视觉通道映射参数主要包括color/col/colour、fill、size、angle、linetype、shape、vjust和hjust,其具体说明如下所示。需要注意的是,有些视觉通道调整参数只适应于类别型变量,比如linetype、shape。

(1)color/col/colour、fill和alpha的属性都是与颜色相关的视觉通道映射参数。其中,color/col/colour是指点(point)、线(line)和填充区域(region)轮廓的颜色;fill是指定填充区域(region)的颜色;alpha是指定颜色的透明度,数值范围是从0(完全透明)到1(不透明)。

(2)size是指点(point)的尺寸或线的(line)宽度,默认单位为pt,可以在geom_point()函数绘制的散点图基础上,添加size的映射,从而实现气泡图的绘制。

(3)angle是指角度,只有部分几何对象有,如geom_text()函数中文本的摆放角度、geom_spoke()函数中短棒的摆放角度。

(4)vjust和hjust都是与位置调整有关的视觉通道映射参数。其中,vjust是指垂直位置微调,在(0, 1)区间的数字或位置字符串:0="buttom", 0.5="middle", 1="top",区间外的数字微调比例控制不均;hjust是指水平位置微调,在(0, 1)区间的数字或位置字符串:0="left", 0.5="center", 1="right",区间外的数字微调比例控制不均。

(5)linetype是指定线条的类型,包括白线(0="blank")、实线(1="solid")、短虚线(2="dashed")、点线(3="dotted")、点横线(4="dotdash")、长虚线(5="longdash")、短长虚线(6="twodash")。

(6)shape是指点的形状,为[0, 25]区间的26个整数,分别对应方形、圆形、三角形、菱形等26种不同的形状,如图1-6-5所示。只有21~26号的点的形状有填充颜色(fill)的属性,其他都只有轮廓颜色(color)的属性。

图1-6-5 R中ggplot2包可供选择的形状

R ggplot2的geom_×××()系列函数,其基础的展示元素可以分成四类:点(point)、线(line)、多边形(polygon)和文本(text),将表1-6-1中ggplot2的常见函数归类为如表1-6-2所示。ggplot2每个函数的具体参数可以通过在RStudio右下角的“help”中输入函数名查找,或者在左下角的“Console”控制台中输入:?函数名,比如:? ? geom_point()。

表1-6-2 ggplot2常见函数的主要视觉通道映射

图1-6-6所示为同一数据集中不同的视觉通道映射效果。使用read.csv()函数:df<-read.csv("Facet_Data.csv", header = TRUE),可以读入数据集df, df是总共有4列的数据集:tau、SOD、age和Class(Control、Impaired和Uncertain),其数据框前6行如图1-6-7所示。

图1-6-6中的4张图表使用的都是geom_point()函数,其参数包括x、y、alpha(透明度)、colour(轮廓色)、fill(填充颜色)、group(分组映射的变量)、shape(形状)、size(大小)、stroke(轮廓线条的粗细)。图1-6-6(a)是将离散数值型变量age映射到散点的大小(size),然后散点图转换成气泡图,气泡的大小对应于age的数值;图1-6-6(b)是将age映射到散点的大小(size)和填充颜色(fill), ggplot2会自动将填充颜色映射到颜色条(colorbar);图1-6-6(c)是将离散类别型变量Class映射到散点的填充颜色(fill), ggplot2会自动将不同的填充颜色对应类别的数据点,从而绘制多数据系列的散点图;图1-6-6(d)是将离散数值型变量age和离散类别型变量Class分别映射到散点的大小(size)和填充颜色(fill)。

图1-6-6 不同的视觉通道映射效果

图1-6-7 数据框前6行

另外,还有不用作变量的视觉通道映射参数,但是有比较重要的视觉通道映射:字体(family)和字型(fontface)。其中,字型分为:plain(常规体)、bold(粗体)、italic(斜体)、bold.italic(粗斜体)。常用于geom_text等文本对象;字体内置的只有3种:sans、serif、mono,但是可以通过扩展包extrafont来将其他字体转换为ggplot2可识别的标准形式,还可以通过showtext包以图片的形式将字体插入到ggplot2绘制的图表中。不同的字体和字型组合如图1-6-8所示。

图1-6-8 不同的字体和字型组合

1.6.3 度量调整

度量用于控制变量映射到视觉对象的具体细节,比如:X轴和Y轴、alpha(透明度)、colour(轮廓色)、fill(填充颜色)、linetype(线形状)、shape(形状)等,它们都有相应的度量函数,如表1-6-3所示。根据视觉通道映射的变量属性,将度量调整函数分成数值型和类别型两大类。R ggplot2的默认度量为scale_×××_identity()。需要注意的是:scale_*_manual()表示手动自定义离散的度量,包括colour、fill、alpha、linetype、shape和size等视觉通道映射参数。

在表1-6-3中,X轴和Y轴度量用于控制坐标轴的间隔与标签的显示等信息,会在1.6.4节时再进行详细介绍。颜色作为数据可视化中尤为重要的部分,colour和fill会在1.7节时再进行详细介绍。在实际的图表绘制中,我们很少使用,因为这很难观察到透明度的映射变化。每个度量调整函数的具体参数可以使用RStudio的“help”界面或者查看ggplot2的官方手册ggplot2的官方手册:https://ggplot2.tidyverse.org/reference/index.html

表1-6-3 ggplot2常见度量调整函数

图1-6-9为散点图不同度量的调整效果,图1-6-9(a)是将数值离散型变量age映射到气泡的大小(size),再使用scale_size(range=c(a, b))调整散点大小(size)的度量,range表示视觉通道映射变量转化后气泡面积的映射显示范围。图1-6-9(b)是在图1-6-9(a)的基础上添加了颜色的映射,使用scale_fill_distiller(palette="Reds")函数将数值离散型变量age映射到红色渐变颜色条中,其中,direction= 0表示颜色是从浅到深渐变的(注意:需要加载RColorBrewer包,才能使用“Reds”颜色主题)。图1-6-9(c)是将类别离散型类别变量Class映射到不同的填充颜色(fill)和形状(shape),使用scale_*_manual()手动自定义fill和shape的度量。图1-6-9(d)是将数值离散型变量age和类别离散型变量Class分别映射到散点的大小(size)和填充颜色(fill),然后scale_size()和scale_fill_manual()分别调整气泡大小(size)的映射范围与填充颜色(fill)的颜色数值。

图1-6-9 不同的度量调整效果

关键是,要学会合理地使用视觉通道映射参数,并调整合适的度量。可视化最基本的形式就是简单地把数据映射成彩色图形。它的工作原理就是大脑倾向于寻找模式,你可以在图形和它所代表的数字间来回切换。1985年,AT&T贝尔实验室的统计学家威廉·克利夫兰(William Cleveland)和罗伯特·麦吉尔(Robert McGill)发表了关于图形感知和方法的论文[18]。研究焦点是确定人们理解上述视觉暗示(不包括形状)的精确程度,最终得出如图1-6-10所示的数值型数据使用不同视觉暗示的精确程度排序。

图1-6-10 克利夫兰和麦吉尔的视觉暗示排序[18]

我们能用到的视觉暗示通常有长度、面积、体积、角度、弧度、位置、方向、形状和颜色(色相和饱和度)。所以正确地选择哪些视觉暗示就取决于你对形状、颜色、大小的理解,以及数据本身和目标。不同的图表类型应该使用不同的视觉暗示,合理的视觉暗示组合能更好地促进读者理解图表的数据信息。如图1-6-11所示,相同的数据系列采用不同的视觉暗示的组合共有6种,分析结果如表1-6-4所示。

表1-6-4 图1-6-11系列图表的视觉暗示组合分析结果

根据表1-6-4可知,图1-6-11(f)是最优的视觉暗示组合结果,既能保证很容易区分数据系列,也保证图表很美观,同时也适应于彩色与黑白两种印刷方式。当图1-6-11(f)采用黑白印刷时,色相视觉暗示会消除,只保留位置+方向+形状,如图1-6-11(c)所示,但是这样也能容易区分数据系列,保证读者正确、快速地理解数据信息。表1-6-5展示了图1-6-11系列图表的视觉暗示组合代码与说明。

图1-6-11 不同视觉暗示的组合结果

表1-6-5 图1-6-11系列图表的视觉暗示组合代码与说明

在表1-6-5中,我们需要重点理解fill、color、size、shape等视觉通道映射参数的具体位置,主要是何时应该在aes()内部,何时应该在aes()外部的区别。

· 当我们指定的视觉通道映射参数需要进行个性化映射时(即一一映射),应该写在aes()函数内部,即每一个观测值都会按照我们指定的特定变量值进行个性化设定。典型情况是需要添加一个维度,将这个维度按照颜色、大小、线条等方式针对维度向量中每一个记录值进行一一设定。

· 当我们需要统一设定某些图表元素对象(共性,统一化)时,此时应该将其参数指定在aes()函数外部,即所有观测值都会按照统一属性进行映射,例如size=5, linetype="dash", color="blue"。典型情况是需要统一所有点的大小、颜色、形状、透明度,或者线条的颜色、粗细、形状等。这种情况下不会消耗数据源中的任何一个维度或者度量指标,仅仅是对已经呈现出来的图形元素的外观属性做了统一设定。

1.6.4 坐标系

在编码数据的时候,需要把数据系列放到一个结构化的空间中,即坐标系,它赋予X轴、Y轴坐标或给出经纬度表示的意义。图1-6-12展示了三种常用的坐标系,分别为直角坐标系(rectangular coordinate)、极坐标系(polar coordinate)和地理坐标系(geographic coordinate)。它们几乎可以满足数据可视化的所有需求。

图1-6-12 常用坐标系

1.直角坐标系

直角坐标系,也叫作笛卡儿坐标系,是最常用的坐标系,如图1-6-13所示。我们经常绘制的条形图、散点图或气泡图,就是直角坐标系。坐标系所在平面叫作坐标平面,两坐标轴的公共原点叫作直角坐标系的原点。X轴和Y轴把坐标平面分成四个象限,右上方的叫作第一象限,其他三个部分按逆时针方向依次叫作第二象限、第三象限和第四象限。象限以数轴为界,横轴、纵轴上的点不属于任何象限。通常在直角坐标系中的点可以记为:(x, y),其中x表示X轴的数值,y表示Y轴的数值。

图1-6-13 直角坐标系下的散点图和气泡图

ggplot2的直角坐标系包括coord_cartesian()、coord_fixed()、coord_flip()和coord_trans()四种类型。ggplot2中的默认类型为coord_cartesian(),其他坐标系都是通过直角坐标系画图,然后变换过来的。在直角坐标系中,可以使用coord_fixed()固定纵横比,在绘制华夫饼图和复合型散点饼图时,我们需要使纵横比为1:coord_fixed(ratio = 1)。

我们在绘制条形图或者水平箱形图时,需要使用coord_flip()翻转坐标系。它会将X轴和Y轴坐标对换,从而可以将竖直的柱形图转换成水平的条形图。

在原始的直角坐标系上,坐标轴上的刻度比例尺是不变的,而coord_trans()坐标系的坐标轴上刻度比例尺是变化的,这种坐标系应用很少,但不是没用,可以将曲线变成直线显示。如果数据点在某个轴方向的密集程度是变化的,不便于观察,则可以通过改变比例尺来调节,使数据点集中显示,更加方便观察。

三维直角坐标系的投影方法 在绘图软件中,三维直角坐标系中有投影这个参数:正交投影(orthographic projection)和透视投影(perspective projection),如图1-6-14所示。读者的眼睛就好比三维渲染场景中的相机。而相机存在两种投影方法。一种是正交投影,也叫平行投影(parallel projection),即进入相机的光线与投影方向是平行的。另一种是透视投影,即所有的光线相交于一点。不管是plot3D包还是lattice包的三维图表绘制函数,都存在这样一个参数可以调整三维坐标系的透视程度,这个参数对三维图表美观程度的展示尤为重要。

图1-6-14 两种不同形式的投影方法

直角坐标系还可以扩展到多维空间。例如,三维空间可以用(x, y, z)三个值对来表示三维空间中数据点的位置。如果再拓展到平行坐标系(parallel coordinate),则可以用于对高维几何和多元数据的可视化,这时,我们可以使用R中GGally包的ggparcoord()函数实现平行坐标系的绘制。

2.极坐标系

雷达图、饼图等就是极坐标系。你可能只用到了角度,还没有用到半径,图1-6-15为极坐标下的柱形图(南丁格尔玫瑰图)。

图1-6-15 极坐标下的柱形图

极坐标系是指在平面内由极点、极轴和极径组成的坐标系。在平面上取定一点O,称为极点。从O出发引一条射线Ox,称为极轴。再取定一个单位长度,通常规定角度取逆时针方向为正。这样,平面上任一点P的位置就可以用线段OP的长度ρ,以及从OxOP的角度θ来确定,有序数对(ρ, θ)就称为P点的极坐标,记为Pρ, θ); ρ称为P点的极径,指数据点到圆心的距离;θ称为P点的极角,指数据点距离最右边水平轴的角度。

极坐标系的最右边点是零度,角度越大,逆时针旋转越多。距离圆心越远,半径越大。极坐标系在绘图中没有直角坐标系用得多,但在角度和方向两个视觉暗示方面有很好的优势,往往可以绘制出很出人意料的精美图表。

R ggoplot2使用coord_polar()函数可以将坐标系从直角坐标系转换到极坐标系,具体语句为:coord_polar(theta = "x", start = 0, direction = 1, clip = "on"),其中,theta表示要极坐标化的中心轴,即X轴转化为圆周,Y轴转化为半径;direction表示排列方向,direction=1表示顺时针,direction=-1表示逆时针;start表示起始角度,以距离12点针的弧度衡量,具体位置与direction的参数有关,若direction为1则在顺时针start角度处,若direction为-1则在逆时针start角度处。注意:极坐标转化比较耗费计算机资源,最好先用如下语句清空内存:rm(list = ls()); gc()。

3.地理坐标系

位置数据的最大好处就在于它与现实世界的联系,用地理坐标系可以映射位置数据。位置数据的形式有许多种,包括经度(longitude)、纬度(latitude)、邮编等。通常用纬度和经度来描述相对于赤道和子午线的角度。纬度线是东西向的,标识地球上的南北位置;经度线是南北向的,标识地球上的东西位置。相对于直角坐标系,纬度就好比水平轴,经度就好比垂直轴。也就是说,相当于使用了平面投影。

由于球面上任何一点的位置都是用地理坐标经纬度(λ, φ)表示的,而平面上的点的位置是用直角坐标(x, y)或极坐标(ρ, θ)表示的,所以要想将地球表面上的点转移到平面上,则必须采用一定的方法来确定地理坐标与平面直角坐标或极坐标之间的关系。这种在球面和平面之间建立点与点之间函数关系的数学方法,就是地图投影方法。地图投影的实质就是将地球椭球面上的地理坐标转化为平面直角坐标。用某种投影条件将投影球面上的地理坐标点一一投影到平面坐标系内,以构成某种地图投影。

地图投影方法有20多种,其中常用的有墨卡托投影(Mercator projection)、兰勃特等角割圆锥投影(Lambert's conic conformal projection)、阿伯斯正轴等积割圆锥投影(Albers equal-area conic projection)、等距圆柱投影(cylindrical equidistant projection)等。具体来说,不同区域常用的地图投影方法不同。墨卡托投影法又称正轴等角圆柱投影,是一种等角的圆柱形地图投影。以此投影法绘制的地图上,经纬线与任何位置皆垂直相交,使世界地图可以绘制在一个长方形上。由于可显示任意两点间的正确方位,航海用途的海图、航路图大多以此方式绘制。在该投影中线型比例尺在图中任意一点周围都保持不变,从而可以保持大陆轮廓投影后的角度和形状不变(即等角);但墨卡托投影法会使面积产生变形,极点的比例甚至达到了无穷大。

R ggplot2使用coord_map()函数和coord_quickmap()函数可以设定坐标系为地理空间坐标系。其中coord_quickmap()函数是一种保留经纬直线的快速近似绘制的地理坐标系,它最适合靠近赤道的较小区域展示。coord_map()函数可以通过设定projection投影参数,从而实现不同投影的地理空间坐标系,包括墨卡托投影、兰勃特等角圆锥投影、Albers等积正割圆锥投影、等距圆柱投影和正交投影等。

4.坐标系的转换

选择合适的坐标系有利于数据的清晰表达,直角坐标系与极坐标系的转换如图1-6-16所示。使用极坐标系可以将数据以365度围绕圆心排列。极坐标图可以让用户方便地看到数据在周期、方向上的变化趋势,而对连续时间段的变化趋势的显示则不如直角坐标系。

图1-6-16 坐标系的转换

极坐标系的表示方法为Pρ, θ),平面直角坐标系的表示方法为Qx, y)。极坐标系中的两个坐标rθ可以由下面的公式转换为直角坐标系下的坐标值:

x=ρcosθ

y=ρsinθ

而在直角坐标系中,由xy两个坐标计算出极坐标下的坐标:

其中,要满足x不等于0。在x = 0的情况下:若y为正数时,则θ = 90°(π/2 radians);若y为负数时,则θ = 270°(3π/2radians)。

5.坐标轴度量

坐标系指定了可视化的维度,而坐标轴的度量则指定了在每一个维度里数据映射的范围。坐标轴的度量有很多种,你也可以用数学函数定义自己的坐标轴度量,但是基本上都属于图1-6-17所示的坐标轴度量。这些坐标轴度量主要分为三种,包括数字(侧重数据的对数变化)、分类坐标轴度量和时间坐标轴度量。其中,数字坐标轴度量包括线性坐标轴度量、对数坐标轴度量、百分比坐标轴度量三类,而分类坐标轴度量包括分类坐标轴度量和顺序坐标轴度量两类。

图1-6-17 不同类型的标尺[19]

在R ggplot2中,数字坐标轴度量包括:scale_x/y_continuous(), scale_x/y_log10(), scale_x/y_sqrt(), scale_x/y_reverse();分类坐标轴度量包括scale_x/y_discrete();时间坐标轴度量包括:scale_x/y_date(),scale_x/y_datetime(), scale_x/y_time()。这些度量的主要参数包括:① name表示指定坐标轴名称,也将作为对应的图例名;②breaks表示指定坐标轴刻度位置,即粗网格线位置;③labels表示指定坐标轴刻度标签内容;④limits表示指定坐标轴显示范围,支持反区间;⑤expand表示扩展坐标轴显示范围;⑥trans表示指定坐标轴变换函数,自带有exp()、log()、log10()等函数,还支持scales包内的其他变换函数,如scales::percent()百分比刻度、自定义等。图1-6-18(b)就是在图1-6-18(a)的基础上添加了scale_x_continuous()和scale_y_continuous()以调整X轴和Y轴的刻度与轴名:

  X轴度量:scale_x_continuous(name="Time(d)", breaks=seq(0,20,2))
  Y轴度量:scale_y_continuous(breaks=seq(0,90,10), limits=c(0,90), expand=c(0,1))

图1-6-18 直角坐标系度量的调整

线性坐标轴度量(linear scale)上的间距处处相等,无论处于坐标轴的什么位置。因此,在尺度的低端测量两点间的距离,和在尺度高端测量的结果是一样的。然而,对数坐标轴度量(logarithmic scale)是一个非线性的测量尺度,用在数量有较大范围的差异时。像里氏地震震级、声学中的音量、光学中的光强度,以及溶液的pH值等。对数尺度以数量级为基础,不是一般的线性尺度,因此每个刻度之间的商为一定值。若数据有以下特性时,用对数尺度来表示会比较方便:

(1)数据有数量级的差异时,使用对数尺度可以同时显示很大和很小的数据信息;

(2)数据有指数增长或幂定律的特性时,使用对数尺度可以将曲线变为直线表示。

图1-6-19(a)的X轴和Y轴都为线性尺度,而图1-6-19(b)X轴仍为线性尺度,将Y轴转变成对数尺度,就可以很好地展示很大和很小的数据信息。

        图1-6-19(a): scale_y_continuous(breaks=seq(0,2.1,0.5), limits=c(0,2))
        图1-6-19(b): scale_y_log10(name='log(value)', limits=c(0.00001,10))

图1-6-19 坐标轴标尺的转换

分类坐标轴度量(categorical scale):数据不仅仅包括数值,有时候还包括类别,比如不同实验条件、实验样品等测试得到的数据。分类标尺通常和数字标尺一起使用,以表达数据信息。条形图就是水平X轴为数字标尺、垂直Y轴为分类标尺;而柱形图是水平X轴为分类标尺、垂直Y轴为数字标尺,如图1-6-20所示。其中,条形图和柱形图一个重要的视觉调整参数就是分类间隔,但是它和数值没有关系(如果是多数据系列,那么还包括一个视觉参数:系列重叠)。另外,饼图和圆环图也是数字尺度和分类尺度的组合。

图1-6-20 分类标尺与数字标尺的组合使用

注意 对于柱形图、条形图和饼图最好对数据先排序后再进行展示。对于柱形图和条形图,把数据从大到小排序,最大的位置放置在最左边或者最上边。而饼图的数据要从大到小排序,最大的从12点位置开始。

常见的相关性系数图的X、Y轴都为分类标尺,如图1-6-21所示。相关系数图一般都是三维及以上的数据,但是使用二维图表显示。其中,X列、Y列为都为类别数据,分别对应图表的X轴和Y轴;Z列为数值信息,通过颜色饱和度、面积大小等视觉暗示表示。图1-6-21(a)使用颜色饱和度和颜色色相综合表示Z列数据;图1-6-21(b)使用方块的面积大小及颜色综合表示Z列数据,从图中很容易观察到哪两组变量的相关性最好。

图1-6-21 分类尺度的使用

相关系数

相关系数(correlation coefficient)是用以反映变量之间相关关系的密切程度的统计指标。它是一种非确定性的关系,相关系数是研究变量之间线性相关程度的量。由于研究对象的不同,相关系数有如下几种定义方式。

(1)简单相关系数:又叫相关系数或线性相关系数,一般用字母r表示,用来度量两个变量间的线性关系。图1-6-21的相关性图就是用来研究多个变量两两之间的简单相关关系的。

(2)复相关系数:又叫多重相关系数。复相关是指因变量与多个自变量之间的相关关系。例如,某种商品的季节性需求量与其价格水平、职工收入水平等现象之间呈复相关关系。

(3)典型相关系数:是先对原来各组变量进行主成分分析,得到新的线性关系的综合指标,再通过综合指标之间的线性相关系数来研究原各组变量间的相关关系。

时间坐标轴度量(time scale):时间是连续的变量,你可以把时间数据画到线性度量上,也可以将其分成时刻、星期、月份、季节或者年份,如图1-6-22所示。时间是日常生活的一部分。随着日出和日落,在时钟和日历里,我们每时每刻都在感受和体验着时间。所以我们会经常遇见时间序列的数据,时间序列的数据常用柱形图、折线图或者面积图表示,有时候使用极坐标图也可以很好地展示数据,因为时间往往存在周期性,以天(day)、周(week)、月(month)、季(season)或年(year)为一个周期。

需要注意的是:R ggplot2的时间坐标轴度量函数scale_×××_date()要求变量是Date格式;scale_×××_datetime()要求变量是POSIXct格式;scale_×××_time()要求变量是hms格式。

图1-6-22 时间序列图表

1.6.5 图例

图例作为图表背景信息的重要组成部分,对图表的完整与正确表达尤为重要。R ggplot2的guide_colorbar()/guide_colourbar()函数用于调整连续变量的图例;guide_legend()函数用于离散变量的图例,也可以用于连续变量。

guides()函数将guide_colorbar和guide_legend两种图例嵌套进去,方便映射与处理,如guides(fill= guide_colorbar()),对多个图例共同处理的时候尤为有效。另外,我们也可以在scale_×××()度量中指定guide类型,guide ="colorbar"或guide ="legend"。

其中,尤为重要的部分是图例位置的设定,R ggplot2默认是将图例放置在图表的右边("right"),但是我们在最后添加的theme()函数中,用legend.position设定图例的位置。legend.position可以设定为"right"、"left"、"bottom"和"top"。

在使用ggplot2绘图的过程中,控制图例在图中的位置利用theme(legend.position)参数,该参数对应的设置为:"none"(无图例)、"left"(左边)、"right"(右边)、"bottom"(底部)、"top"(头部), legend.position也可以用两个元素构成的数值向量来控制,如c(0.9,0.7),主要是设置图例在图表中间所在的具体位置,而不是图片的外围。数值大小一般在0~1之间,超出数值往往导致图例隐藏。如果图例通过数值向量设定在图表的具体位置,那么最好同时设定图例背景(legend.background)为透明或者无。图1-6-23使用的是theme_classic()内置的图表系统主题,使用theme()函数调整图例的具体位置。图1-6-23(a)所示图例的默认设定语句为:

        theme(legend.background = element_rect(fill="white"),
              legend.position="right")

上述语句表示将图例的背景设为白色填充的矩形,位置设定为图表的右边。图1-6-23(b)将图例的位置设定为图表内部的左上角,并将图例背景(legend.background)设置为无。其中c(0.2,0.8)表示图例的位置放置在图表内部X轴方向20%、Y轴方向80%的相对位置。

        theme(legend.background = element_blank(),
            legend.position=c(0.2,0.8))

图1-6-23 图例位置的调整

1.6.6 主题系统

主题系统包括绘图区背景、网格线、坐标轴线条等图表的细节部分,而图表风格主要是指绘图区背景、网格线、坐标轴线条等的格式设定所展现的效果。ggplot2图表的主题系统的主要对象包括文本(text)、矩形(rect)和线条(line)三大类,对应的函数包括element_text()、element_rect()、element_line(),另外还有element_blank()表示该对象设置为无,具体如表1-6-6所示。其中,我们使用比较多的系统对象是坐标轴的标签(axis.text.x、axis.text.y)、图例的位置与背景(legend.position和legend.background)。X轴标签(axis.text.x)在绘制极坐标柱形图和径向柱形图时会用于调整X轴标签的旋转角度,Y轴标签(axis.text.y)也会用于时间序列峰峦图的Y轴标签的替换等,具体可见后面图表案例的讲解。

表1-6-6 主题系统的主要对象

由于ggplot2主题设置的内部函数及参数非常多,所以不建议新手直接学习。针对新手,建议使用ggThemeAssist包进行主题设置,用鼠标而不是代码,这样更加方便,也可以直接套用主题模板。

1.ggThemeAssist包

使用ggThemeAssist包,需要先安装shiny包。安装好该包后,在RStudio界面选择“Tools”→“Addins”→“ggplot Theme Assistant”选项,弹出界面如图1-6-24所示。具体使用方法:首先运行函数要画图的ggplot2代码,以加载到内存;然后选中该画图函数,如ggplot;再选择“Tools”→“Addins”→“ggplot Theme Assistant”选项,就会出现一个交互式的shiny弹窗,在该弹窗上用鼠标操作;在弹窗中处理完后,点击右上角的“Done”按钮,就将主题代码输出到需要的位置,最后对代码进行微调即可。但是需要注意的是:有的地方可能会少括号或引号。

图1-6-24 ggplot Theme Assistant操作界面

2.套用主题模板

R语言的主题模板包包括ggthemes、ggtech、ggthemer、ggsci、cowplot等。其中ggsci包就是专门为学术图表开发的包ggsci包的参考手册:https://nanx.me/ggsci/articles/ggsci.html。R ggplot2自带的主题模板也有多种,包括theme_gray()、theme_minimal()、theme_bw()、theme_light()、theme_test()、theme_classic()等函数。相同的数据及数据格式,可以结合不同的图表风格,如图1-6-25所示。下面挑选几种具有代表性的图表风格讲解。

(1)图1-6-25(a)是R ggplot2风格的散点图,使用R ggplot2 Set3的颜色主题,绘图区背景填充颜色为RGB(229, 229, 229)的灰色,以及白色的网格线[主要网格线的颜色为RGB(255, 255, 255),次要网格线的颜色为RGB(242, 242, 242)]。这种图表风格给读者清新脱俗的感觉,推荐使用在PPT演示中。

(2)图1-6-25(d)的绘图区背景填充颜色为RGB(255,255, 255)的白色,无主要和次要网格线,没有过多的背景信息。当图表尺寸较小时,仍然可以清晰地表达数据内容,不像图1-6-24(b)会因为背景线条太多而显得凌乱,其常应用在学术期刊的论文中展示数据。

(3)图1-6-25(e)在图1-6-25(d)的基础上,将绘图区边框设定为“无”,也没有主要和次要网格线,同样常应用在学术期刊的论文中展示数据。

所以,总的来说,图1-6-25(a)和图1-6-25(b)的风格适合PPT演示,图1-6-25(d)和图1-6-25(e)适合于学术论文展示。其实,不管是使用R、Python,还是Origin、Excel,都可以通过调整绘图区背景、主要和次要网格线、坐标轴线条等的格式,实现如图1-6-25所示的6种不同的图表风格。

图1-6-25 不同的图表风格

1.6.7 位置调整

在geom_×××()函数中,参数position表示绘图数据系列的位置调整,默认为"identity"(无位置调整),这个参数在绘制柱形图和条形图系列时经常用到,用来绘制簇状柱形图、堆积柱形图和百分比堆积柱形图等。ggplot2的位置调整参数如表1-6-7所示。在柱形图和条形图系列中,position的参数有4种:①identity:不做任何位置调整,该情况在多分类柱形图中不可行,序列间会遮盖,但是在多序列散点图、折线图中可行,不存在遮盖问题;②stack:垂直堆叠放置(堆积柱形图); ③dodge:水平抖动放置(簇状柱形图,position=position_dodge()); ④fill:百分比化(垂直堆叠放置,如百分比堆积面积图、百分比堆积柱形图等)。其中,箱形图和抖动散点图的位置调整如图1-6-26所示。构造的数据集为:

        N<-100
        df<-data.frame(group=rep(c(1,2), each=N*2),
                      y=append(append(rnorm(N,5,1), rnorm(N,2,1)), append(rnorm(N,1,1), rnorm(N,3,1))),
                      x=rep(c("A", "B", "A", "B"), N))

表1-6-7 ggplot2位置调整参数

图1-6-26 箱形图和抖动散点图的位置调整

新手工具

对于R语言新手,在这里推荐一款RStudio的插件esquisse:可通过交互操作实现简单的ggplot2图表,自动生成并导出绘图代码,供用户再做进一步的调整与美化。esquisse的安装可以通过使用devtools包来完成:

        devtools::install_github("dreamRs/esquisse")

如果要在RStudio中启动esquisse,既可以通过点击RStudio界面的“Tools”→“Addins”→“ggplot2 builder”选项;也可以在“Console”命令框中输入语句:esquisse:::esquisser(),其界面如图1-6-27所示。

图1-6-27 esquisse交互操作界面

高手必备

特别强调的是,要想熟练使用ggplot2绘制图表,就必须深入理解ggplot与geom对象之间的关系。在实际绘图语句中存在如表1-6-8所示的3种情况。在表中的案例,我们使用的数据集为向量排序函数sort()和正态分布随机数生成函数rnorm()构造的df1和df2。

        N<-20
        df1 <- data.frame(x=sort(rnorm(N)), y=sort(rnorm(N)))
        df2 <- data.frame(x=df1$x+0.1*rnorm(N), y=df1$y+0.1*rnorm(N))

ggplot与geom对象之间的关系主要体现在如下两点。

· ggplot(data=NULL, mapping = aes()):ggplot内有data、mapping两个参数,具有全局优先级,可以被之后的所有geom对象所继承(前提是geom内未指定相关参数)。

· geom_×××(data=NULL, mapping = aes()):geom对象内同样有data和mapping参数,但geom内的data和mapping参数属于局部参数,仅作用于geom对象内部。

表1-6-8 ggplot与geom对象之间的关系情况