4.1 简介

qplot()的局限性在于它只能使用一个数据集和一组图形属性映射,解决这个问题的办法就是使用图层。每个图层可以有自己的数据集和图形属性映射,附加的数据元素可通过图层添加到图形中。

一个图层由五个部分组成:

  1. 数据:必须是一个数据框;
  2. 一组图形属性映射,用来设定数据集中的变量如何映射到该图层的图形属性;
  3. 几何对象,用来指定在图层中用哪种几何对象来绘图;
  4. 统计变换,返回一个包含新变量的数据框;
  5. 位置调整,通过调整元素位置来避免图形重合。

4.2 创建绘图对象

当我们调用qplot()时,它其实为我们做了很多幕后工作:创建一个图形对象,添加图层并且展示结果。在整个过程中它使用了很多默认的绘图参数。如果想要手动创建图形对象,就用用到ggplot()函数。只有在新添加的图层里设定了新参数时,默认值才会被修改。

4.3 图层

layer(geom, geom_params, stat, stat_params, data, mapping, position)

p <- ggplot(diamonds, aes(x = carat))
p <- p + layer(geom = "bar", geom_params = list(fill = "steelblue"), stat = "bin",
stat_params = list(binwidth = 2))
p

该代码生成一个组距为2,铁青色的直方图。

下面的快捷函数生成与上述代码完全相同的图层。

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(可选):选择一种调整对象重合的方式。

sleep:这是哺乳动物睡眠数据集的更新和扩展版本。

> head(msleep)
# A tibble: 6 x 11
name genus vore order conservation sleep_total sleep_rem sleep_cycle
<chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 Chee~ Acin~ carni Carn~ lc 12.1 NA NA
2 Owl ~ Aotus omni Prim~ NA 17 1.8 NA
3 Moun~ Aplo~ herbi Rode~ nt 14.4 2.4 NA
4 Grea~ Blar~ omni Sori~ lc 14.9 2.3 0.133
5 Cow Bos herbi Arti~ domesticated 4 0.7 0.667
6 Thre~ Brad~ herbi Pilo~ NA 14.4 2.2 0.767
# ... with 3 more variables: awake <dbl>, brainwt <dbl>, bodywt <dbl>
  • name:常用名
  • genus,vore:食肉动物、杂食动物还是食草动物?
  • order,conservation:动物的保护状况
  • sleep_total:睡眠总量,以小时为单位
  • sleep_rem:快速眼动睡眠,以小时为单位
  • sleep_cycle:睡眠周期的长度,以小时为单位
  • awake:醒着的时间,以小时为单位
  • brainwt:脑重量(公斤)
  • bodywt:体重(公斤)

图层被添加到用ggplot()或qplot()创建的图形对象上。

## 在用ggplot创建的图形对象上添加图层
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对象,所以可以存储到变量里去,这有利于代码避繁就简。例如,一组图形可以先用不同的数据进行初始化,然后加上相同的图层。下面的例子创建了一个带有半透明深蓝色回归线的图层。

bestfit <- geom_smooth(method = "lm", se = F, colour = alpha("steelblue", 0.5),
size = 2)
qplot(sleep_rem, sleep_total, data = msleep) + bestfit
qplot(bodywt, brainwt, data = msleep, log = "xy") + bestfit

4.4 数据

ggplot2对数据的要求很简单:必须是一个数据框。

要使用相同的代码,不同的数据集绘图,只需改变数据集即可。下面的例子用%+%来添加新的数据集以代替原来的数据集。

p <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) + geom_point()
p
mtcars <- transform(mtcars, mpg = mpg^2)
p %+% mtcars

数据是以副本而不是引用的形式存储到图形对象中的。

4.5 图形属性映射

aes(x = weight, y = height, colour = age)

aes()函数用来将数据变量映射到图形中,从而使变量成为可以被感知的图形属性。

注意最好不要指定数据集以外的变量(例如diamonds$carat),因为这样无法将绘图所用的数据都封装到一个对象里。每个aes()函数里的变量都包含于默认数据集或者图层数据集中,是保证ggplot2对象都是自含型的重要方式之一,这样方便存储和重复使用。但可以使用变量的函数值作为参数。

4.5.1 图和图层

默认的图形属性可以在图形对象初始化时设定,或者过后用+修改。如下例,图形对象p中默认的映射可以在新图层里扩充或修改。

## 使用默认的参数映射来添加图层
p <- ggplot(mtcars, aes(x = mpg, y = wt))
p + geom_point()

p + geom_point(aes(colour = factor(cyl)))

p + geom_point(aes(y = disp))

4.5.2 设定和映射

除了可以将一个图形属性映射到一个变量,也可以在图层的参数里将其设定为单一值。图形属性可以根据观测的不同而变化,但是参数则不行。

p <- ggplot(mtcars, aes(mpg, wt))
p + geom_point(colour = "darkblue")

# 注意这里将颜色映射到'darkblue'与上面将颜色设定给'darkblue'的区别
p + geom_point(aes(colour = "darkblue"))

上面的图将点的颜色设定为深蓝色,下面的图将colour映射到"darkblue"颜色,实际上是先创建了一个只含有"darkblue"字符的变量,然后将colour映射到这个新变量。

在使用qplot()函数的时候,可以将某个值放到I()里来实现映射,例如colour = I("darkblue")。

4.5.3 分组

图中所有离散型变量的交互作用被设定为分组的默认值,通常情况下这样可以正确地给数据分组,但是如果没能正确分组或者图中没有离散型变量,那么就需要自定义分组结构,即将group映射到一个在不同组有不同取值的变量。当现有的单个变量不能够正确地分组,而两个变量的组合可以正确分组时,可以使用interaction()函数。


> library(nlme)
> head(Oxboys)
Grouped Data: height ~ age | Subject
Subject age height Occasion
1 1 -1.0000 140.5 1
2 1 -0.7479 143.4 2
3 1 -0.4630 144.8 3
4 1 -0.1643 147.1 4
5 1 -0.0027 147.7 5
6 1 0.2466 150.2 6

牛津男孩的身高:

  • Subject:为实验中每个男孩提供唯一标识符的有序因子
  • age:给出标准年龄的数字向量(无量纲)
  • height:一个数字向量,给出男孩的身高(厘米)
  • Occasion:把年龄从一个连续的变量转换成一个计数的结果而得到的一个有序因素,这些轻微不平稳的数据可以被认为是平稳的。

多个分组与单个图形属性

将数据分为若干组,并用相同的方式对每个组进行渲染。当从总体上来查看数据时,我们通常希望区分每个个体(group)而不是识别他们(colour)。这在含有多个个体的纵向数据中是很常见的,而这类图形也常被称为“细面图”。

p <- ggplot(Oxboys, aes(age, height, group = Subject))
p + geom_line()

不同图层上的不同分组

希望在所有男孩的年龄和身高图中添加一条光滑线条,新图层需要一个不同的分组图形属性,group=1,这样绘制出的线条就是基于整体的。

p <- ggplot(Oxboys, aes(age, height, group = Subject))
p + geom_line() + geom_smooth(aes(group = 1), method = "lm", size = 1.5, se = F)
# 或
qplot(age, height, data = Oxboys, group = Subject, geom = "line") + geom_smooth(aes(group = 1),
method = "lm", size = 1.5, se = F)

修改默认分组

如果图像中含有离散型变量,而我们希望绘制连接所有分组的线条,那么可以采取绘制交互作用图、轮廓图以及平行坐标图所用的策略。这里绘制各个测量时期身高的箱线图并添加个体轨迹。

ggplot(Oxboys, aes(Occasion, height)) + geom_boxplot() +
geom_line(aes(group = Subject), colour = "#3366FF")

4.5.4 匹配图形属性和图像属性

线条和路径遵循差一原则:观测点比线段数目多一,第一条线段使用第一个观测的图形属性,第二条线段使用第二个观测点的图形属性,以此类推,这意味着最后一个观测的图形属性将不会被线段用到。

df <- data.frame(x = 1:3, y = 1:3, colour = c(1, 3, 5))
qplot(x, y, data = df, colour = factor(colour), size = I(5)) + geom_line(aes(group = 1),
size = 2)
qplot(x, y, data = df, colour = colour, size = I(5)) + geom_line(size = 2)

线段平稳地从一种图形属性变换到另一种图形属性。

## 用线性插值法做颜色渐变线条
xgrid <- with(df, seq(min(x), max(x), length = 50))
interp <- data.frame(x = xgrid, y = approx(df$x, df$y, xout = xgrid)$y, colour = approx(df$x,
df$colour, xout = xgrid)$y)
qplot(x, y, data = df, colour = colour, size = I(5)) + geom_line(data = interp,
size = 2)

多边形可用fill参数进行填充,这是整体对象的一个属性。

## 图4.7 一个条形图(左)按组分解后得到的叠加条形图(右),两者轮廓相同。
qplot(color, data = diamonds)
qplot(color, data = diamonds, fill = cut)

若不用fill而用colour,则会对边界上色,效果远不如上图明显。

qplot(color, data = diamonds, colour = cut)

4.6 几何对象

几何图形对象,简称为geom,他执行着图层的实际渲染,控制着生成的图形类型。例如,用电几何对象将会生成散点图,而用线几何对象就会生成折线图。下表列出了ggplot2中所有可用的几何对象。

每个几何对象都有一组它能识别的图形属性和一组绘图所需的值。例如,一个点含有颜色、大小和形状等图形属性,以及x和y位置坐标。一个条形含有高度、条宽、边界颜色和填充颜色等图形属性。下表中列出了所有几何对象的图形属性。

每个几何对象都有一个默认的统计变换,并且每一个统计变换都有一个默认的几何对象。这些默认值如下表所示。

名称 描述 默认的统计变换 图形属性
abline 线,由斜率和截距决定 abline colour,linetype,size
area 面积图 identity colour,fill,linetype,size,x,y 
bar 条形图,以x轴为底的矩形 bin colour,fill,linetype,size,weight,x
bin2d 2维热图 bin2d colour,fill,linetype,size,weight,xmax,xmin,ymax,ymin
blank 空白,什么也不画 identity  
boxplot 箱线图 boxplot colour,fill,lower,middle,size,upper,weight,x,ymax,ymin
contour 等高线图 contour colour,linetype,size,weight,x,y
crossbar 带有水平中心线的盒子图 identity colour,fill,linetype,size,x,y,ymax,ymin
density 光滑密度曲线图 density colour,fill,linetype,size,weight,x,y
density2d 二维密度等高线图 density2d colour,linetype,size,weight,x,y
dotplot “点直方图”,用电来表示观测值的个数 bindot colour,fill,x,y
errorbar 误差棒 indetity colour,linetype,size,width,x,ymax,ymin
errorbarh 水平的误差棒 identity colour,linetype,size,width,y,ymax,ymin
freqpoly 频率多边形图 bin colour,linetype,size
hex 用六边形表示的2维热图 binhex colour,fill,size,x,y
histogram 直方图 bin colour,fill,linetype,size,weight,x
hline 水平线 hline colour,linetype,size
jitter 给点添加扰动,减轻图形重叠问题 identity colour,fill,shape,size,x,y
line 按照x坐标的大小顺序依次连接各个观测值 identity colour,linetype,size,x,y
linerange 一条代表一个区间的竖直线 identity colour,linetype,size,x,ymax,ymin
map 基准地图里的多边形 identity colour,fill,linetype,size,x,y,map_id
path 按数据的原始顺序连接各个观测值 identity colour,linetype,size,x,y
point 点,用来绘制散点图 identity colour,fill,shape,size,x,y
pointrange 用一条中间带点的竖直线代表一个区间 identity colour,fill,linetype,shape,size,x,y,ymax,ymin
polygon 多边形,相当于一个有填充的路径 identity colour,fill,linetype,size,x,y
quantile 添加分位数回归线 quantile colour,linetype,size,weight,x,y
raster 高效的矩形瓦片图 identity colour,fill,linetype,size,x,y
rect 2维的矩形图 identity colour,fill,linetype,size,xmax,xmin,ymax,ymin
ribbon 色带图,连续的x值所对应的y的范围 identity colour,fill,linetype,size,x,ymax,ymin
rug 边际地毯图 identity colour,linetype,size
segment 添加线段或箭头 identity colour,linetype,size,x,xend,y,yend
smooth 添加光滑的条件均值线 smooth alpha,colour,fill,linetype,size,weight,x,y
step 以阶梯形式连接各个观测值 identity colour,linetype,size,x,y
text 文本注释 identity angle,colour,hjust,label,size,vjust,x,y
tile 瓦片图 identity colour,fill,linetype,size,x,y
violin 小提琴图 ydensity weight,colour,fill,size,linetype,x,y
vline 竖直线 vline colour,linetype,size

4.7 统计变换

统计变换,简称stat,通常以某种方式对数据信息进行汇总。例如,平滑是一个很有用的统计变换,它能在一些限制条件的约束下计算给定x值时y的平均值。下表中列出了可用的统计变换。为了阐明在图形中的意义,一个统计变换必须是一个位置尺度不变量,即$f(x + a) = f(x) + a$并且$f(b \cdot x) = b \cdot f(x)$,这样才能保证当改变数据的标度时,数据变换的展现形式不变。

名称 描述
bin 计算封箱数据
bin2d 计算矩形封箱内的观测值个数
bindot 计算“点直方图”的封箱数据
binhex 计算六边形热图的封箱数据
boxplot 计算组成箱线图的各种元素值
contour 三维数据的等高线
density 一维密度估计
density2d 二维密度估计
function 添加新函数
identity 不对数据进行统计变换
qq 计算qq图的相关值
quantile 计算连续的分位数
smooth 添加光滑曲线
spoke 将角度和半径转换成xend和yend
sum 计算每一个单一值的频数,有助于解决散点图的图形重叠问题
summary 对每个x所对应的y值做统计描述
summary2d 对2维矩形封箱设定函数
summaryhex 对2维六边形封箱设定函数
unique 删除重复值
ydensity 小提琴图,计算1维y轴方向的核密度函数估计值

4.8 位置调整

所谓位置调整,就是对该层中的元素的位置进行微调,位置调整一般多见于处理离散型数据。下表中列出了可用的位置调整函数。

名称 描述
dodge 避免重叠,并排放置
fill 堆叠图形元素并将高度标准化为1
identity 不做任何调整
jitter 给点添加扰动避免重合
stack 将图形元素堆叠起来

在条形图中可以很好地解释不同类型的位置调整。

## 应用于条形图的三种位置调整。从左到右依次是:堆叠(stacking),填充
## (filling)和并列(dodging)
dplot <- ggplot(diamonds, aes(clarity, fill = cut))
dplot + geom_bar(position = "stack")
dplot + geom_bar(position = "fill")
dplot + geom_bar(position = "dodge")

4.9 整合

4.9.1 结合几何对象和统计变化

## 直方图的三种变体。频率多边形(frequency
## polygon)(左);散点图,点的大小和
## 高度都映射给了频率(中);热图(heatmap)用颜色来表示频率。
d <- ggplot(diamonds, aes(carat))
d + stat_bin(aes(ymax = ..count..), binwidth = 0.1, geom = "area")
d + stat_bin(aes(size = ..density..), binwidth = 0.1, geom = "point", position = "identity")
d + stat_bin2d(aes(y = 1, fill = ..count..), binwidth = 0.1, geom = "tile", position = "identity")

4.9.2 显示已计算过的统计量

如果已有汇总过的数据,并且希望直接使用它,而不进行其他的统计变换,可以使用stat_identity(),然后将合适的变量映射到相应的图形属性中。

4.9.3 改变图形属性和数据集

个体拟合预测,并添加预测线。

model <- lme(height ~ age, data = Oxboys, random = ~1 + age | Subject)
oplot <- ggplot(Oxboys, aes(age, height, group = Subject)) + geom_line() age_grid <- seq(-1, 1, length = 10)
subjects <- unique(Oxboys$Subject) preds <- expand.grid(age = age_grid, Subject = subjects)
preds$height <- predict(model, preds) oplot + geom_line(data = preds, colour = "#3366FF", size = 0.4)

绘制残差图,后修改模型为带二次项的拟合模型(效果较好)。

Oxboys$fitted <- predict(model)
Oxboys$resid <- with(Oxboys, fitted - height) oplot %+% Oxboys + aes(y = resid) + geom_smooth(aes(group = 1)) model2 <- update(model, height ~ age + I(age^2))
Oxboys$fitted2 <- predict(model2)
Oxboys$resid2 <- with(Oxboys, fitted2 - height) oplot %+% Oxboys + aes(y = resid2) + geom_smooth(aes(group = 1))

我们对图形的修改是非常容易的,更新数据并重新作图时并不需要重新运行oplot,这正是ggplot2所秉承的理念:使得反复拟合和评估模型变得轻松而自然。

总结

ggplot2(4) 用图层构建图像的更多相关文章

  1. ggplot2(11) 总结回顾&案例练习

    从2020年2月20到2月27日,3月13日到2020年3月16日,学习了ggplot2:数据分析与图形艺术(哈德利·威克姆 著 统计之都 译),历时12天.另外,3月6日到3月9日参加了美赛,也用到 ...

  2. R语言 ggplot2包

    R语言  ggplot2包的学习   分析数据要做的第一件事情,就是观察它.对于每个变量,哪些值是最常见的?值域是大是小?是否有异常观测? ggplot2图形之基本语法: ggplot2的核心理念是将 ...

  3. [转]ggplot2用法简单介绍

    简介 ggplot2包是基于Wilkinson在<Grammar of Graphics>一书中所提出的图形语法的具体实现, 这套图形语法把绘图过程归纳为data, transformat ...

  4. (数据科学学习手札37)ggplot2基本绘图语法介绍

    一.简介 ggplot2是R语言中四大著名绘图框架之一,且因为其极高的参数设置自由度和图像的美学感,即使其绘图速度不是很快,但丝毫不影响其成为R中最受欢迎的绘图框架:ggplot2的作者是现任Rstu ...

  5. ggplot2入门与进阶(上)

    出处:http://www.cellyse.com/how_to_use_gggplot2_part1/ ggplot2包是基于Wilkinson在<Grammar of Graphics> ...

  6. ggplot2(1) 简介

    1.1 简介 ggplot2是一个用来绘制统计图形(数据图形)的R软件包,与其他大多数的图形软件包不同,ggplot2是由其背后的一套图形语法所支持的.ggplot2可以绘制出很多美观度的图形,同时能 ...

  7. R实战 第五篇:绘图(ggplot2)

    ggplot2包实现了基于语法的.连贯一致的创建图形的系统,由于ggplot2是基于语法创建图形的,这意味着,它由多个小组件构成,通过底层组件可以构造前所未有的图形.ggplot2可以把绘图拆分成多个 ...

  8. ggplot2入门与进阶(下)

    出处:http://www.cellyse.com/how_to_use_gggplot2_part2/ 更多实战 例一 Michaelis-Menten动力学方程 这个例子中采用出自文献中的一组有关 ...

  9. Dockerfile构建实践

    Dockerfile构建实践 本文介绍了用于构建有效图像的推荐最佳实践和方法. Docker通过从一个Dockerfile文本文件中读取指令来自动构建映像,该文本文件按顺序包含构建给定映像所需的所有命 ...

随机推荐

  1. worship|spurs|drowns out|frauds|expell|spray with|deposit|moist|gave a sigh

    to have or show a strong feeling of respect and admiration for God or a god 敬奉,崇拜,信仰(上帝或神) On the is ...

  2. [洛谷P3806] [模板] 点分治1

    洛谷 P3806 传送门 这个点分治都不用减掉子树里的了,直接搞就行了. 注意第63行 if(qu[k]>=buf[j]) 不能不写,也不能写成>. 因为这个WA了半天...... 如果m ...

  3. POJ 1251 & HDU 1301 Jungle Roads

    题目: Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign ...

  4. JStorm:任务调度

    前一篇文章 JStorm:概念与编程模型 介绍了JStorm的基本概念以及编程模型方面的知识,本篇主要介绍自己对JStorm的任务调度方面的认识,主要从三个方面介绍: 调度角色 调度方法 自定义调度 ...

  5. Docker跨主机容器之间的通信macvlan

    找两台测试机: [root@docker1 centos_zabbix]# docker network ls NETWORK ID NAME DRIVER SCOPE 19ac9a55bedb br ...

  6. iPhoneSE2要在印度独家生产真得没戏?

    现在,关于iPhone SE2的消息层出不穷,总的来说,它是一款真实存在的手机,整体性能和iPhone5X/SE相似,大概可能差不多会加上一些"无线充电"之类的无聊功能.普通消费者 ...

  7. (六)mybatis-spring集成完整版

    mybatis-spring集成完整版 一.项目整体 mybatis接口层.mapper层 Service层 Test调用测试 二.自动生成代码-mybatis generator 主要修改: 接口. ...

  8. String.slice

    String.slice(start, end)start从字符串的哪个index开始截取 默认值0 如果为负值,则从字符串的尾部向前倒推indexend到从字符串的哪个index结束截取 默认值st ...

  9. APP内计费规范出台 手游乱收费现象能被遏制?

    手游乱收费现象能被遏制?" title="APP内计费规范出台 手游乱收费现象能被遏制?"> 在一个混乱.无秩序的环境中竞争,虽然有可能不择手段地获取更多的利益,但 ...

  10. Python---6条件判断与循环

    条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= ...