一点碎碎念:今天开始看第三章Toolbox, 主要讲的是图层的用法,在图像的基础上,图层可以让plot的信息更加丰富和完整,于是就有了怎样加标签,加注释等等。这些内容虽然不难但是很琐碎,由于R基础薄弱,有些代码理解起来需要时间。所以,在这里我想先以读书笔记和翻译的形式,记录为主,尽量去逐字逐句理解。除了添加注释、标签等之外,使用图层还可以完成箱线图、多边形等等多种群组几何对象类型的图,还可以绘制曲面图等。下面是第三章的主要内容:

使用图层的三个主要目的:

  1. 展示数据:绘制原始数据时唯一的一层(数据层)

  2. 展示数据的统计摘要:在数据背景下展示模型的统计预测效果,模型层通常绘制在数据层之上

  3. 添加额外的元数据(metadata)、上下文信息和注释:也称背景层,了解数据的背景信息或强调数据中的某些特征,一般在最后绘制。

1. 基本图形类型

几何对象是ggplot2的基本组成部分,可以独立构建图形。他们都是二维的,主要函数有 geom_area()geom_bar()geom_linegeom_point()geom_polygon()geom_tile()等等。这些函数包括x,y两个主要属性,另外也可以接受 colorsize两个图形属性,他们构成了基本的数据层。

我们可以通过使用 +添加图层

df <- data.frame(x = c(3, 1, 5),y = c(2, 4, 6),label = c("a","b","c")
)
df
p <- ggplot(df, aes(x, y, label = label)) +labs(x = NULL, y = NULL) + # Hide axis labeltheme(plot.title = element_text(size = 12)) # Shrink plot title
p + geom_point() + ggtitle("point")
p + geom_text() + ggtitle("text")
p + geom_bar(stat = "identity") + ggtitle("bar")
p + geom_tile() + ggtitle("raster")
p + geom_line() + ggtitle("line")
p + geom_area() + ggtitle("area")
p + geom_path() + ggtitle("path")
p + geom_polygon() + ggtitle("polygon")

以上命令运行后可依次生成散点图、含标签的散点图、条形图、色深图、线条图、面积图、路径图和多边形图等八个图,其中 ggtitle()是给各个图片添加注释/命名


2. 添加标签(label)

主要函数 geom_text():和散点类似,就是将point换成了文字。它包括以下几种参数:

  • size:设置字体大小

  • angle:设置倾斜角度

  • family:可设置字体,下面代码中的 "sans", "serif", "mono"代表三种字体, "sans"是默认字体。

df <- data.frame(x = 1, y = 3:1, family = c("sans", "serif", "mono"))
ggplot(df, aes(x, y)) +geom_text(aes(label = family, family = family))

此外还有两个字体安装包

– showtext, https://github.com/yixuan/showtext, by Yixuan Qiu, makes GD-independent plots by rendering all text as polygons.

– extrafont, https://github.com/wch/extrafont, by Winston Chang, converts fonts to a standard format that all devices can use.

  • fontface:可设置粗体或斜体, “plain”默认普通值, “bold” 粗体、 “italic”斜体。

df <- data.frame(x = 1, y = 3:1, face = c("plain", "bold", "italic"))
ggplot(df, aes(x, y)) +geom_text(aes(label = face, fontface = face))

  • vjust 和 hjust 可以设置字体对齐方式。 vjust (“bottom”, “middle”, “top”, “inward”, “outward”); hjust (“left”, “center”, “right”, “inward”, “outward”)。最常用的路线之一是 “inward”:它将文本对齐到主画面的中间:

df <- data.frame(x = c(1, 1, 2, 2, 1.5),y = c(1, 2, 1, 2, 1.5),text = c("bottom-left", "bottom-right","top-left", "top-right", "center")
)
ggplot(df, aes(x, y)) +geom_text(aes(label = text))  # 字母不能全部在画面中
ggplot(df, aes(x, y)) +geom_text(aes(label = text), vjust = "inward", hjust = "inward")  # 字母全部在画面中

  • nudge()参数可以设置文字距原坐标点的距离,在散点和文字同时存在时很有必要,这是文字是一个注释的作用,如果不添加该参数,点和文字就会重合。

df <- data.frame(trt = c("a", "b", "c"), resp = c(1.2, 3.4, 2.5))
ggplot(df, aes(resp, trt)) +geom_point() +geom_text(aes(label = paste0("(", resp, ")")), nudge_y = -0.25) +         # y轴负方向下移0.25xlim(1, 3.6)               # 设定x轴取值区间

  • check_overlap:查找重复值。当注释中有大量重复时,设置 check_overlap=TRUE可以自动删除重复标签。

以耗油量数据为例:

library(ggplot2)
mpg
ggplot(mpg, aes(displ, hwy)) +geom_text(aes(label = model)) +xlim(1, 8)
ggplot(mpg, aes(displ, hwy)) +geom_text(aes(label = model), check_overlap = TRUE) +xlim(1, 8)

另外,与 geom_text() 类似的是 geom_label(),它与geom_text的区别自动在文字后方绘制一个圆角矩形标签,当需要在复杂的背景上标注文字时可以使用。

label <- data.frame(waiting = c(55, 80),eruptions = c(2, 4.3),label = c("peak one", "peak two")
)
ggplot(faithfuld, aes(waiting, eruptions)) +geom_tile(aes(fill = density)) +geom_label(data = label, aes(label = label))

学会了在图中添加标签,可以替代图例


3. 注释(Annotations)

注释可以在你的图上添加一些额外的元数据,可以使用以下函数:

  • geom_text():在指定点添加标签(见上文)

  • geom_rect():可强调图形中感兴趣的矩形区域。包括 xminxmaxyminymax

  • geom_line()geom_path()geom_segment():在图形中添加线条; arrow()可以用来添加箭头

  • geom_vline()geom_hline():向图形添加垂直线或水平线

  • geom_abline():向图形添加任意斜率和截距地直线

然后我们用“失业率数据集”来举例:

ggplot(economics, aes(date, unemploy)) +
geom_line()

下面我们想在图中展现一下不同政党执政时期失业率的高低情况:

presidential <- subset(presidential, start > economics$date[1])          ## 设置数据集,economics$date[1]是指定了数据集中data一列的第一行数据
ggplot(economics) +geom_rect(aes(xmin = start, xmax = end, fill = party),ymin = -Inf, ymax = Inf, alpha = 0.2,data = presidential) +geom_vline(aes(xintercept = as.numeric(start)),data = presidential,colour = "grey50", alpha = 0.5) +geom_text(aes(x = start, y = 2500, label = name),data = presidential,size = 3, vjust = 0, hjust = 0, nudge_x = 50) +geom_line(aes(date, unemploy)) +                ## 数据集中的两列数据来源scale_fill_manual(values = c("blue", "red"))    ## scale是标度函数

(疑问: party这个对象的数据不知道从哪里来的)

生成图片:

如果我们想使用同样的方法在图片中添加一个单独的注释,方法有点复杂,因为首先要创建一个数据框:

library(ggplot2)
economics
yrng <- range(economics$unemploy)
xrng <- range(economics$date)   ## range 是取提取范围的子集,最大值和最小值
caption <- paste(strwrap("Unemployment rates in the US have
+  varied a lot over the years", 40), collapse = "\n")      ## 设置题目内容
ggplot(economics, aes(date, unemploy)) +
geom_line() +
geom_text(
aes(x, y, label = caption),
data = data.frame(x = xrng[1], y = yrng[2], caption = caption),
hjust = 0, vjust = 1, size = 4
)

上述代码可以用 annotate()来简化 geom_text()部分:

ggplot(economics, aes(date, unemploy)) +
geom_line() +
annotate("text", x = xrng[1], y = yrng[2], label = caption,
hjust = 0, vjust = 1, size = 4)

生成图片:

注释,在分面状态下的组间比较的时也非常有用。下面要做一组关于钻石质量(carat)和价格(price)比较的2d热图,按照切割品质(cut)进行分面:

ggplot(diamonds, aes(log10(carat), log10(price))) +geom_bin2d() +facet_wrap(~cut, nrow = 1)

4. 群组几何对象(Collective Geoms)

在ggplot2中,几何对象大致可以分为个体(individual)几何对象和群组(collective)两种类型。群组几何对象可以多角度的展现数据结果。

group(分组)这种图形属性可以用来设置:哪些观测值控制哪种图形元素

举例:纵向数据集Oxboys(nlme包)记录了26个男生(subject)在9个不同时期(occasion)中测定的身高(height)和中心化年龄(age)。

data(Oxboys, package = "nlme")
> head(Oxboys)
#>  Subject   age  height Occasion    ## 以下是输出结果
#> 1  1    -1.0000  140    1
#> 2  1    -0.7479  143    2
#> 3  1    -0.4630  145    3
#> 4  1    -0.1643  147    4
#> 5  1    -0.0027  148    5
#> 6  1     0.2466  150    6

多个分组+单个图形属性

当我们想从总体上查看数据,将数据中的每个个体区分开,然后用同样的方式映射。这在含有多个个体的纵向数据中很常见,叫“细面图”(spaghetti plot)。

例如,我们想在整体上观察26个男生的成长轨迹(并不区分哪条线是那个男生),就可以在映射 aes()中添加参数 group=Subject

ggplot(Oxboys, aes(age, height, group = Subject)) +geom_point() +geom_line()

如果不加 group这个参数,我们只会得到一条将所有点连起来的奇怪的折线,这就毫无疑义了

在不同图层进行分组

如果我们想要将不同水平下的数据加以整合得到一个汇总信息,这时,基本的数据图层上是每个个体的数据,我们可以在第二个数据层上展示整体组群的信息。

例如在上面的例子中,我们想根据所有男孩的年龄和身高在图中添加一个平滑线条,如果按照上面的方式,在第一层函数中直接添加 group=Subject就会给每个男孩的线条上加一个平滑曲线,这不能得到我们想要的结果:

ggplot(Oxboys, aes(age, height, group = Subject)) +
geom_line() +
geom_smooth(method = "lm", se = FALSE)

这时我们应该把分组参数放到另一个图层中,正确的代码如下:

ggplot(Oxboys, aes(age, height)) +
geom_line(aes(group = Subject)) +
geom_smooth(method = "lm", size = 2, se = FALSE)

修改默认分组

在这里首先补充说明一下变量的分类:变量按其数值表现是否连续,分为连续变量和离散变量。

离散变量:指变量值可以按一定顺序一一列举,通常以整数位取值的变量。如职工人数、工厂数、机器台数等。

连续变量:在一定区间内可以任意取值的变量叫连续变量,其数值是连续不断的,相邻两个数值可作无限分割,即可取无限个数值

当离散变量存在时,一般就会将其认为是默认分组变量。

如果图像中含有离散型变量,而你却想绘制连接所有分组的线条。这时就要修改默认分组。或者在新图层中设定一个新的分组,就能将二者结合起来。

在上个例子中,绘制各个时期(Occasion)和身高(height)的箱线图,离散型变量Occasion默认为分组变量:

ggplot(Oxboys, aes(Occasion, height)) +geom_boxplot()

然后要在此基础上添加个体轨迹,这时只添加 geom line()函数不能达到预期效果,因为它还会默认Occasion为分组变量,这时应该将 aes(group=Subject)添加在 geom line()函数中,另外添加颜色属性 colour将第二个图层区分开:

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

匹配图形属性和图形对象

如何将个体的图形属性映射给整体图形属性。

  • 线段和路径类

例如建立一个数据框,包括三个数据点,两条连接三点的线段。数据点比线段条数多一,线段的图形属性是由起始点的图形属性决定的,所以第一条线段使用第一个数据点的图形属性,第二条线段使用第二个数据点的图形属性,而第三个点的图形属性将不会被用到。下面代码生成图片的颜色是随着数据点,呈现离散状态。

library(ggplot2)
df <- data.frame(x = 1:3, y = 1:3, colourname = c(1,3,5))
ggplot(df, aes(x, y, colour = factor(colourname))) +geom_line(aes(group = 1), size = 2) +    ## group = 1 默认分组设置geom_point(size = 5)

下面修改可以将颜色属性设置为渐变状态,但是数据点还是突出的:

ggplot(df, aes(x, y, colour = colourname)) +geom_line(aes(group = 1), size = 2) +geom_point(size = 5)

在复杂一些,利用“线性插值法”可以将线段平稳地在图形属性间变化:

啥是“线性插值法”:已知坐标 (x0, y0) 与 (x1, y1),要得到 [x0, x1] 区间内某一位置 x 在直线上的值。

library(ggplot2)
df <- data.frame(x = 1:3, y = 1:3, colour = c(1,3,5))
xgrid <- with(df, seq(min(x), max(x), length = 50))   ## seq()是生成一组数字
interp <- data.frame(x = xgrid,y = approx(df$x, df$y, xout = xgrid)$y,   ##approx()是排序colour = approx(df$x, df$colour, xout = xgrid)$y
)
ggplot(interp, aes(x, y, colour = colour)) +geom_line(size = 2) +geom_point(data = df, size = 5)

  • 多边形等

对于多边形这类几何图像,当所有个体的图形属性都相同时,可以使用 fill()参数。

当图形映射对象是离散型对象时,默认将群组几何对象分解成更小的部分。

如下例,耗油量数据集(mpg)中,用柱状图表示不同类别的汽车数量:

library(ggplot2)
mpg
ggplot(mpg, aes(class)) +geom_bar()

进一步,通过 fill()参数,用不同颜色表示drv(动力传动系统:前轮f,后轮r,四轮4),填充每个class:

library(ggplot2)
mpg
ggplot(mpg, aes(class, fill = drv)) +geom_bar()

drv是离散型变量,所以可以用不同的颜色区分

如果根据连续型变量hwy(高速公路行驶记录每加仑行驶的英里数)填充class,如果不添加分组信息,则不会有不同颜色填充。

ggplot(mpg, aes(class, fill = hwy)) +
geom_bar()

如果在 fill()后面添加 group()参数,设置按 hwy分组:

ggplot(mpg, aes(class, fill = hwy, group = hwy)) +
geom_bar()

就可以形成按照hwy数量大小,渐变填充的状态。

5. 曲面图(Surface Plots)

ggplot2包不能绘制3D曲面图像,但是可绘制能表示3D图的2D图像,比如等高线图、着色瓦片图、气泡图等

geom_contour() 等高线图:

library(ggplot2)
faithfuld
# A tibble: 5,625 x 3eruptions waiting density<dbl>   <dbl>   <dbl>1      1.60    43.0 0.003222      1.65    43.0 0.003843      1.69    43.0 0.004444      1.74    43.0 0.004985      1.79    43.0 0.005426      1.84    43.0 0.005747      1.88    43.0 0.005928      1.93    43.0 0.005949      1.98    43.0 0.00581
10      2.03    43.0 0.00554
# ... with 5,615 more rows
ggplot(faithfuld, aes(eruptions, waiting)) +geom_contour(aes(z = density, colour = ..level..))

geom_raster() 着色瓦片图:

ggplot(faithfuld, aes(eruptions, waiting)) +
geom_raster(aes(fill = density))

气泡图:

library(ggplot2)
faithfuld
# Bubble plots work better with fewer observations
small <- faithfuld[seq(1, nrow(faithfuld), by = 10), ]
ggplot(small, aes(eruptions, waiting)) +geom_point(aes(size = density), alpha = 1/3) +scale_size_area()

参考资料:

  1. Hadley Wickham(2016). ggplot2. Springer International Publishing. doi: 10.1007/978-3-319-24277-4

  2. 《R语言应用系列丛书·ggplot2:数据分析与图形艺术》

猜你喜欢

  • 热文:1高分文章 2不可或缺的人 3图表规范

  • 一文读懂:1微生物组 2寄生虫益处 3进化树

  • 必备技能:1提问 2搜索  3Endnote

  • 文献阅读 1热心肠 2SemanticScholar 3geenmedical

  • 扩增子分析:1图表解读 2分析流程 3统计绘图  4功能预测

  • 科研经验:1云笔记  2云协作 3公众号

  • 系列教程:1Biostar 2微生物组  3宏基因组

  • 生物科普 1肠道细菌 2人体上的生命 3生命大跃进  4细胞的暗战 5人体奥秘

写在后面

为鼓励读者交流、快速解决科研困难,我们建立了“宏基因组”专业讨论群,目前己有国内外150+ PI,1300+ 一线科研人员加入。参与讨论,获得专业解答,欢迎分享此文至朋友圈,并扫码加主编好友带你入群,务必备注“姓名-单位-研究方向-职称/年级”。技术问题寻求帮助,首先阅读《如何优雅的提问》学习解决问题思路,仍末解决群内讨论,问题不私聊,帮助同行。

学习16S扩增子、宏基因组科研思路和分析实战,关注“宏基因组”

ggplot2笔记2:图层的使用——基础、怎样加标签、注释相关推荐

  1. ggplot2笔记9:绘图需要的数据整理技术

    本书的最后一个部分,Part III,Data Analysis.主要包括三个章节,今天先来看第九章: ggplot2绘图基础系列: 1初识ggplot2绘制几何对象 2图层的使用-基础.加标签.注释 ...

  2. ggplot2笔记4 语法基础

    本公众号R语言和ggplot2笔记系列作品为袁志林老师学员创作,请关注今天二条袁老师组博后招聘启事. ggplot2绘图基础: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础 ...

  3. ggplot2笔记5:通过图层构建图像

    ggplot2绘图基础系列: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础.怎样加标签.注释 3工具箱--误差线.加权数.展示数据分布 4语法基础 Build a Plot ...

  4. ggplot2笔记8:主题设置、存储导出

    ggplot2绘图基础系列: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础.怎样加标签.注释 3工具箱--误差线.加权数.展示数据分布 4语法基础 5通过图层构建图像 6标 ...

  5. ggplot2笔记7:定位(分面和坐标系)

    ggplot2绘图基础系列: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础.怎样加标签.注释 3工具箱--误差线.加权数.展示数据分布 4语法基础 5通过图层构建图像 6标 ...

  6. ggplot2笔记6:标度、轴和图例

    ggplot2绘图基础系列: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础.怎样加标签.注释 3工具箱--误差线.加权数.展示数据分布 4语法基础 5通过图层构建图像 Sc ...

  7. ggplot2笔记3:工具箱——误差线、加权数、展示数据分布

    ggplot2绘图基础: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础.怎样加标签.注释 今天我们学习第三章的最后几节,其中的"绘制地图"部分,因为我木 ...

  8. R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(配置数据点抖动显示jitter)实战

    R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(配置数据点抖动显示jitter)实战 目录 R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(配置 ...

  9. R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色自定义配置)实战

    R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框颜色自定义配置)实战 目录 R语言使用ggplot2包使用geom_boxplot函数绘制基础分组箱图(分组箱体框 ...

最新文章

  1. 常用的异常检测算法有哪些?
  2. Java实用教程笔记 泛型与集合框架
  3. 如何在Cordova Android 7.0.0 以下版本集成最新插件 极光插件为例
  4. 手机验证短信设计与代码实现(转载)
  5. .net软件工程师笔试题目
  6. termux apache php,要啥自行车之Termux:将我们的(Android)安卓手机打造成全能的服务器...
  7. ubuntu 14.04 LTS(64bit) Anacoda2环境下安装gensim
  8. php软件开发--nginx服务器(待补充)
  9. raspberry pi_如何进行Raspberry Pi聚会
  10. 小米9将在MWC2019上登场:后置三摄拍照令人“中毒”
  11. python中intvar_Python的IntVar设置
  12. c语言spoc期末考试及答案,MOOC-SPOC测试题(部分答案)(至数组一章)-C语言-宣城校区2016年.docx...
  13. 平面四边形八节点等参单元的平面有限元分析程序
  14. W ndows7蓝屏0x00000024,Win7电脑蓝屏0x00000024错误的解决方法
  15. Asp.net学习总结
  16. python中offset的意思_python覆盖从offset1到offset2的字节
  17. Xilinx FPGA 将寄存器放入IOB中
  18. 嵌入式硬件设计-常见处理器介绍
  19. 零售行业的六大主要EDI报文
  20. Elixir应用简介

热门文章

  1. 把集成测试和单元测试写一起是一种什么体验?
  2. 系列文章|OKR与敏捷(二):实现全栈敏捷
  3. 简洁好用的项目管理工具推荐~马起来
  4. D001斯图加特~计算机
  5. 死锁产生原因-竞争不可剥夺资源
  6. Linux多用户、多任务的特性
  7. 计算机和网络历史地位,所谓“运营商的文字游戏”,其实是计算机和网络发展的客观历史导致的...
  8. C#获取指定坐标点像素,效率更高快
  9. C#Swagger使用
  10. 玩转python轻松过二级_关于通话的阿里云论坛用户知识和技术交流