购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第一节
散点图

一、ggplot代码的基本用法

让我们从生活满意度调查开始。数据集happy small.csv记录了若干国家2017年的人均GDP和生活满意度分数。受访者被要求用0至10的数值评估自己的满意度,0代表非常不满意,10代表非常满意,每个国家或地区的得分是该国家或地区所有受访者的分数的均值。我们希望用散点图来呈现这两个变量之间的关系。

library(ggplot2)

dat=read.csv("happy small.csv", row.names=1) # 课件中的文件

ggplot()+ # 第1行

geom_point(data=dat, na.rm=TRUE, aes(GDP_percap, Satisfaction), color="blue")+ # 第2行

labs(title="Life Satisfaction VS. GDP per capita") # 第3行

下面我们来解释一下以上ggplot代码的含义。第1行,也就是ggplot函数加一个括号,可以看成是一个必不可少的标记,用来告诉程序我们打算用ggplot画图。如果没有这个标记,后面的所有图层都不会被绘制出来。第2行的geom_point是实际执行绘制散点图图层的命令。其中,data参数指向我们使用的数据, color指向点的颜色(这里是蓝色),na.rm决定处理缺失值的方法。我们给出X坐标和Y坐标的完整的代码是aes(GDP_percap, Satisfaction),这里需要注意的有三点:第一,由于参数x和参数y是位于前端的两个参数,所以参数名可以省略;第二,GDP_percap和Satisfaction并不是位于整个R之中的变量(或者说,不是全局变量),而是被data所指定的数据框dat中具有相应名称的两列;第三,我们不能把X和Y坐标直接放在geom_point函数里,而必须放在aes函数里。第3行代码用于给图表添加标题——我们将会在第三章详细讲述标题等图表附属元素。这几行代码也可以合并为一行,但不管我们是否合并它们,都应该用加号来把它们连接起来——事实上,ggplot中的语句都必须用加号来连接。不过,务必不要在最后一个语句后写加号,否则程序会认为你的代码还没有写完。

以下几种书写方式的效果相同:

qplot(GDP_percap, Satisfaction, data=dat) # 写法1

ggplot()+stat_identity(data=dat, aes(GDP_percap, Satisfaction), geom="point") # 写法2

ggplot(dat)+geom_point(aes(GDP_percap, Satisfaction)) # 写法3

ggplot()+geom_point(data=dat, aes(GDP_percap, Satisfaction)) # 写法4

ggplot()+geom_point(aes(dat$GDP_percap, dat$Satisfaction)) # 写法5

ggplot(dat, aes(GDP_percap, Satisfaction))+geom_point() # 写法6

在上面的代码中,写法1用到了qplot,这个函数用来快速作图;但鉴于我们将要学习ggplot系统的完整代码写法,所以我们无需使用qplot。写法2使用了stat_identity。在ggplot系统中,用来作图的函数有两个系列,一是geom_*系列(如,geom_point),二是stat_*系列。这两个系列的函数所使用的代码不同,但绘图效果是完全相同的。我们只需要学习geom_*系列(它的函数名称更为直观),而不需要学习stat_*系列。

写法3是我们推荐的写法,它把数据放在ggplot里,而把坐标等信息放在图层函数geom_point里。写法4也是我们推荐的写法,它把数据放在了geom_point里,而没有放在ggplot里,这是因为有时我们需要一次绘制多个图层(而不像本例那样只绘制一个图层),而不同图层会使用不同的数据;在此情况下,将数据放在一个图层函数里,意味着这个数据只会被这个图层使用。

写法5没有在任何地方赋值给data参数,而是直接在aes里给出两个向量。

写法6时常出现,它把数据和坐标都放在ggplot中,后边的图层都可以使用这里的数据和坐标,这种写法固然可以简化代码(所以geom_point里可以什么都不写),但也易引起混淆,所以我们不推荐这种写法。

以下两种写法也经常会被用到:

# 写法7

p=ggplot(dat)

p+geom_point(aes(GDP_percap, Satisfaction))

# 写法8

p=ggplot(dat)

q=geom_point(aes(GDP_percap, Satisfaction))

p+q

写法7和写法8的效果与其他写法的效果完全相同。在这两种效果中,ggplot语句并没有被加号直接连接起来,而是被赋值给变量。这种写法在语句较多或我们需要对语句进行搭配组合时会被用到。

二、参数设定

我们以geom_point为例来讲解图层参数的设定。

图层参数可分为两类,一类是放在aes里的参数,本书称其为aes参数;另一类是放在aes外的参数,本书称其为一般参数。color、fill等参数既出现在aes里,又出现在一般参数里,但却在两类参数中发挥着不同作用,对此,我们将在本章第三节进行详细说明。现在,我们只介绍geom_point中较好理解的一般参数:

●data:绘制图表所使用的数据。它可以是tbl_df对象或data.frame对象;其中,后者更为常用,而前者是由tibble包生成的类似于data.frame对象的数据框。

●na.rm:处理缺失值的方法。无论它的值是TRUE还是FALSE(默认),函数都会忽略包含缺失值的个案;只是,当其为FALSE时,函数会弹出警告。事实上,为防止出错,我们最好使用没有缺失值的数据。

●show.legend:是否添加图例。当其为NA(默认)时函数会自动决定是否添加图例,当其为TRUE时图例肯定会出现,当其为FALSE时图例肯定不出现。

●mapping:用aes给出的映射。mapping=aes(...)多会被直接写为aes(...)。而aes里最常用的参数就是x和y参数。

shape:以0至25的整数表示的点的形状,默认值为19。如果你不知道每个数字代表的形状是什么,可以像下文那样把这些点都画出来查看。注意:以21至25表示的点均由两部分组成,一部分是核心,另一部分是轮廓。另外,我们还可以用I()的形式画出字符,括号里可以放一个字母、数字或汉字(见下文示例)。

●size:以数值表示的点的大小(面积,而非半径),默认值为1.5。

●stroke:轮廓的粗细。当形状为21至25的数值时,点的大小取决于两点,一是核心部分的大小,以size表示;二是轮廓的粗细,以stroke表示,默认值为0.5。

●colo(u)r、fill:当形状为0至20时,colo(u)r决定点的颜色;当形状为21至25时,核点的颜色由fill决定,轮廓的颜色由color决定。

●alpha:点的颜色的透明度。注意:当点包含核心和轮廓时,alpha将同时作用于这两者。

下面我们就来看几个使用上述参数的例子。

p=ggplot(dat)+labs(title="Life Satisfaction VS. GDP per capita")

p+geom_point(aes(GDP_percap, Satisfaction), size=5, color="red", alpha=0.5, shape=8)

p+geom_point(aes(GDP_percap, Satisfaction), size=5, color= rainbow(10)) # 图形属性值的长度要么为1,要么与要画的图形的数量相等,否则程序会报错。另外,假如数据有n行,其中3行包含缺失值,那么,若要给出多个属性值的话,也不能仅给n-3个值,而必须给出n个值(与缺失值对应的那个属性值不会被用到)

p+geom_point(aes(GDP_percap, Satisfaction), size=10, color= rainbow(10), shape=I("H")) # 以字符为点(图2-1-1a)

p+geom_point(aes(GDP_percap, Satisfaction), shape=22, size=1: 10, stroke=rep(3, 10), color="grey", fill="yellow")

ggplot()+geom_point(aes(x=0: 25, y=0: 25), size=4.5, shape=0: 25, color="purple", fill="orange") # 查看所有可用形状(图2-1-1b)

图2-1-1 左=图a 以字符为点,右=图b 所有可用形状

## 要注意的是,alpha参数会同时改变color和fill的透明度。(图2-1-2a)因此,如果你只想改变两者之一,就要单独设置alpha

p+geom_point(aes(GDP_percap, Satisfaction), shape=21, size=8, stroke=3, alpha=seq(0.1, 1, length.out=10), color="red", fill="blue")

## 如果只想改变fill的透明度而不改变color的透明度,就需使用scales:: alpha函数预先把fill的透明度设置好(图2-1-2b)

new_blue=scales::alpha("blue", seq(0.1, 1, length.out=10))

p+geom_point(aes(GDP_percap, Satisfaction), shape=21, size=8, stroke=3, color="red", fill=new_blue)

图2-1-2 左=图a同时作用于color和fill的alpha,右=图b单独设置fill的alpha

接下来,我们要说明一般参数与aes参数的区别,或者说,在aes外与在aes里设置属性的区别。

mycolor=c("yellow", "yellow", "purple", "purple") # 假设我们要使用黄色和紫色

ggplot()+geom_point(aes(1: 4, 1: 4), size=8, color=mycolor) # 写法一,把color放在aes外边,按需要画出黄色和紫色点,图例未出现(图2-1-3a) ggplot()+geom_point(aes(1: 4, 1: 4, color=mycolor), size=8) # 写法二,把color放在aes里边,点没有变成黄色和紫色,颜色由图例表示(图2-1-3b)

在第二种写法中,aes并没有真的使用"yellow"和"blue"这两个颜色,而是把它们看成代表两个类别的编号(按字母顺序排列,"blue"是第一类,"yellow"是第二类),并且把两种颜色(默认颜色为"#F8766D"和"#00BFC4",下文会讲到如何更改)分配给相应的点。一个也许更为重要的区别是,aes参数会自动根据变量的取值来分配属性(比如,我们可以设置与数值成正比的透明度),而一般参数只会根据数值在数据框中出现的位置,来使属性跟数值对应起来(比如,出现在数据框中第一行的数据点使用透明度向量中的第一个值,第二行的数据点使用第二个值,以此类推)。关于这两种写法的其他重要区别,我们将在第三节讲解scale_*_*系列函数时提及。

图2-1-3 左=图a color在aes函数外,右=图b color在aes函数内

## 再看一个透明度的例子

myalpha=c(0.5, 0.7, 0.9)

ggplot()+geom_point(aes(x=1: 3, y=1: 3), size=8, color="red", alpha=myalpha) # 使用指定的alpha值

ggplot()+geom_point(aes(x=1: 3, y=1: 3, size=8, color="red", alpha=myalpha)) # 未使用指定值,而是把指定值转化到0.1至1的区间中

#==========

# 练习:使用不同饱和度

#==========

# 用本书第一章讲到的hsv函数画蓝色点,并使点的饱合度依GDP_percap的大小在0.2到0.6之间变动

library(plothelper)

res=scale_free(dat$GDP_percap, left=0.2, right=0.6) # 把GDP_percap转移到0.2至0.6的值域中

co=hsv(h=2/3, # 蓝色在色盘2/3的位置

s=res, # 使用我们生成的饱合度数值

v=1

)

ggplot(dat)+geom_point(aes(GDP_percap, Satisfaction), size=8, color=co)

#==========

# 练习:为点分配随机颜色

#==========

# 散点图可以用来生成幻灯片或海报的背景。下边我们来绘制一张类似达米恩·赫斯特(Damien Hirst)的《派洛宁Y》(Pyronin Y)的散点图(图2-1-4)

图2-1-4 为点随机分配颜色

library(RColor Brewer) # 使用配色方案

nx=15 # 每行点数

ny=12 # 每列点数

all_color=brewer.pal(9, "Set1") # 在RColor Brewer中选择自己喜欢的配色方案

xy=expand.grid(x=1: nx, y=1: ny) # 生成点的位置

set.seed(1); co=sample(all_color, nrow(xy), TRUE) # 设定随机种子并生成多个随机颜色

ggplot(xy)+

geom_point(aes(x, y), color=co, size=4)+

theme_void()+theme(plot.background=element_rect(color=NA, fill="white")) # 这里的theme_void和theme在后边关于主题设置的章节会讲到 UBRmN+N5nMpV46LYiqZm8LiMs6OCbG2fW69e1IVMYzZuE3UndUAWsdDk5HglJKth

点击中间区域
呼出菜单
上一章
目录
下一章
×