《ggplot2:数据分析与图形艺术》
第4章 用图形构建图像
4.1 简介
qplot()的局限性在于它只能使用一个数据集和一组图形属性映射,解决这个问题的办法就是使用图层。每个图层可以有自己的数据集和图形属性映射,附加的数据元素可通过图层添加到图形中。
一个图层由5部分组成:数据,一组图形属性映射,几何对象,统计变换,位置调整。
4.2 创建绘图对象
在创建一个图形对象时,当使用qplot()添加图层并展示结果,在整个过程中使用了很多默认的绘图参数。
如果想手动创建图形对象,就要用到ggplot()函数。
该函数有两个主要的参数:数据和图形属性映射。
参数数据指定绘图所用的默认数据集(必须是数据框类型);映射是需要将图形属性和变量名放到函数aes()的括号里面。> p <- ggplot(diamonds, aes(carat, price, colour=cut))#diamonds是数据,aes()中的carat表示x轴的标度,price表示y轴的标度。> print(p)#绘制一个空的图,只有横纵坐标刻度和标度,因为数据映射还没有加入图层即几何对象。
ggplot(data = NULL, mapping = aes(), …, environment = parent.frame())
4.3 图层
数据映射未生成图形,需要加入一个图层即几何对象,不同图层之间用“+”来添加。
图层设定了一些可选的参数选项:layer(geom, geom_params, stat, stat_params, data, mapping, position)
每个几何对象都对应着一个默认的统计变换和位置调整,每一个统计变换都对应着一个默认的几何对象参数,所欲对于一个图层我们需要设定stat或geom参数即可。
例如:geom_histogram(binwidth=2, fill="steelblue")
所有这类函数都有相同的形式,即以geom_或stat_开头:geom_XXX(mapping, data, ..., stat, position)stat_XXX(mapping, data, ..., geom, position)
它们的参数定义了图层的各个组件:
- mapping(可选):一组图形属性映射,通过aes()函数来设定;
- data(可选):一个数据集,他会修改默认的数据集;
- …:geom或stat的参数,例如直方图的组距(binwidth)或者loess光滑曲线的带宽(bandwidth);也可以用图形属性作为参数,这样该属性就被设定为一个固定的值,而不是被映射给数据集中的一个变量;
- geom或stat(可选):可修改geom默认的stat值,或stat所默认的geom值。它们是一组字符串,包含了将要使用的几何对象或统计变换的名称。使用默认值可得到标准图形,修改默认值可得到新图形;
- position(可选):选择一种调整对象重合的方式。
图层可以被添加到用ggplot()或qplot()创建的图形对象上。实际上qplot()的绘图原理就是先创建图形对象然后再添加图层。下面展示两种绘图方法的等价性。> ggplot(msleep, aes(sleep_rem / sleep_total, awake)) + geom_point()
等价于> qplot(sleep_rem / sleep_total, awake, data=msleep)
绘制散点图
也可以给qplot添加图层> qplot(sleep_rem / sleep_total, awake, data=msleep) + geom_smooth()#添加平滑曲线
等价于> qplot(sleep_rem / sleep_total, awake, data=msleep, geom=c("point","smooth"))
或> ggplot(msleep, aes(sleep_rem / sleep_total, awake)) + geom_point() + geom_smooth()
图层是普通的R对象,可以存储到变量中去,有利于代码避繁就简。例如,一组图形可以先用不同的数据来进行初始化,然后加上相同的图层,如果后面想改变图层,只需要修改一个地方即可。
例如,创建一个带有半透明深蓝色回归线的图层。> library(scales)> bestfit <- geom_smooth(method="lm", se=F, colour=alpha("steelblue", 0.5), size=2)#半透明蓝色回归线> qplot(sleep_rem, sleep_total, data=msleep) + bestfit> qplot(awake, brainwt, data=msleep, log='y') + bestfit#y轴取对数值> qplot(bodywt, brainwt, data=msleep, log='xy') + bestfit#x轴和y轴均取对数值
4.4 数据
ggplot2会从我们给定的数据框中提取绘图所需要的变量,并生成一个新的数据集,而不是直接在原数据上进行数据变换。用**%+%**来添加新的数据集以替代原来的数据集。> p <- ggplot(mtcars, aes(mpg, wt, colour=cyl)) + geom_point()> p
> mtcars> mtcars <- transform(mtcars, mpg=mpg^2)#mpg的值做平方运输再赋值给mpg> p %+% mtcars#绘制运算后的mpg结果绘图
> v <- p %+% mtcars#将绘图结果可以重现赋值给一个变量
在更改数据集时,可以任意改变它的值和维数,但是如果将一个变量从离散型变成连续型或者从连续型变成离散型,那么需要改变相应的默认标度。
数据是以副本而不是引用的形式存储到图形对象中的。这样做有两个重要的好处:其一,如果你的数据改变了,绘图不会改变。其二,ggplot2的对象都是自含型的,所以它们可以被存储(save())到磁盘上,并且之后可以被直接加载运行(load())。
4.5 图形属性映射
aes()函数用来将数据变量映射到图形中,从而使变量成为可以被感知的图形属性。aes()函数里有一系列的图形属性参数:> aes(x=weight, y=height, colour=age)
Aesthetic mapping:x -> weighty -> heightcolour -> age
展示最终的映射结果,并且x,y可以省略。对应数据,例如data=diamonds,变量名直接写carat,不需要写diamonds$carat。
可以使用变量的函数值作为参数。aes(weight, height, colour=sqrt(age))#sqrt(age),age的sqrt函数。
4.5.1 图和图层
默认的图形属性映射可以在图形对象初始化时设定,或者过后用+修改。> p <- ggplot(mtcars)> summary(p)> p <- p + aes(wt, hp)
“+”可以持续的添加图层信息。> p <- ggplot(mtcars, aes(mpg, wt))> p + geom_point()#绘制图形结果为,横坐标为mpg的值,纵坐标为wt的值。> p + geom_point(aes(colour=factor(cyl)))#用factor(cyl)修改图形的颜色,注意这里一定要是有图形属性映射函数aes(),将要映射的内容放入函数中,如果直接写colour=factor(cyl)会报错。> p + geom_point(aes(y=disp))#用disp值修改y坐标的值,但是虽然值进行了替换,但是y轴的坐标名称没有改变(这里需要注意)。> p + geom_point(aes(size=I(5)))> p + geom_point(size=I(5))
两种方法均改变图中点的大小
具体的修改规则如下:
| 操作 | 层图形属性 | 结果 |
|---|---|---|
| 添加 | aes(colour=cyl) | aes(mpg, wt, colour=cyl) |
| 修改 | aes(y=disp) | aes(mpg, disp) |
| 删除 | aes(y=NULL) | aes(mpg) |
一个图层里设定的图形属性映射只对该图层起作用。因此,除非你修改默认的标度,否则坐标标签以及图例标题都会根据图形对象的默认设置而生成。
4.5.2 设定和映射
除了可以将一个图形属性映射到一个变量,你也可以在图层的参数里将其设定为一个单一值(例如,colour=“red”)。图形属性可以根据观测的不同而变化,但是参数则不行。
例如:> p <- ggplot(mtcars, aes(mpg, wt))> p + geom_point(colour="darkblue")#这里将点的颜色设定为深蓝色。
但是上面的方法和下面的方法就存在很大的区别了> p + geom_point(aes(colour="darkblue"))#但这里绘图的结果就存在了很大的差异,绘图的点不是深蓝色的,而是随机配置的颜色
将颜色设定为"darkblue"(第一种图)于将颜色映射到"darkblue"(第二张图)的区别。颜色设定表示直接定制为,当颜色映射到"darkblue"时,"darkblue"将被看作一个普通的字符串,使用默认的颜色标度进行标度转换,结果得到了浅红色的点和图例。
在使用qplot()函数的时候,可以将某个值放到I()里面来实现映射(例如colour=I(“darkblue”))。> need <- mtcars[1:10,c('mpg','wt','cyl')]> need#截取一部分操作数据,其中cyl是用来分类绘图的数据
mpg wt cyl
Mazda RX4 21.0 2.620 6
Mazda RX4 Wag 21.0 2.875 6
Datsun 710 22.8 2.320 4
Hornet 4 Drive 21.4 3.215 6
Hornet Sportabout 18.7 3.440 8
Valiant 18.1 3.460 6
Duster 360 14.3 3.570 8
Merc 240D 24.4 3.190 4
Merc 230 22.8 3.150 4
Merc 280 19.2 3.440 6> subset(need, need$cyl==6)
mpg wt cyl
Mazda RX4 21.0 2.620 6
Mazda RX4 Wag 21.0 2.875 6
Hornet 4 Drive 21.4 3.215 6
Valiant 18.1 3.460 6
Merc 280 19.2 3.440 6> col <- c('red', 'green', 'blue')#设定三种颜色> ggplot(need, aes(mpg, wt, colour=factor(cyl)))+geom_point()+scale_color_manual(values = col)#最终绘图结果会根据你输入的颜色进行绘图
ggplot(need, aes(mpg, wt, colour=factor(cyl)))+geom_point()+scale_color_manual(values = col)
对函数的解释,
ggplot(need, aes(mpg, wt, colour=factor(cyl))),ggplot作图,need表示data,mpg和wt是横纵坐标值,colour表示绘图颜色,factor(cyl)表示对cyl数据产生因子分钟,根据不同的levels值,分组值进行绘图。如果是colour=cyl则不进行分组,直接绘制渐变色散点图。geom_point()散点图。scale_color_manual(values = col)根据分组进行着色,values是col这个向量,分为三种颜色,col <- c(‘red’, ‘green’, ‘blue’),根据cyl的levels值,根据levels的大小值从小到大排序,然后分别对应着进行着色。