ggplot2笔记7:定位(分面和坐标系)
ggplot2绘图基础系列:
1初识ggplot2、基本用法以及如何绘制几何对象
2图层的使用——基础、怎样加标签、注释
3工具箱——误差线、加权数、展示数据分布
4语法基础
5通过图层构建图像
6标度、轴和图例
Positioning
7.1 简介
本章主题是图形的定位。
定位由四个部分组成,前两个在前期讲过,而后两个部分在这章中会详细说到:
位置调整:调整每个图层中出现重叠的对象的位置
位置标度:控制数据到图形的映射
分面:在一个页面上自动摆放多个图形。将数据分为多个子集,然后将每个子集依次绘制到不同面板上
坐标系:控制两个独立的位置标度形成一个二维坐标系,如笛卡尔坐标系
7.2 分面
每个小图都代表不同的数据子集。分面可以快速地分析数据各子集模式的异同。
本节讨论怎样较好微调分面,特别是和位置标度相关的方法。
facet_null()
:默认,无分面,单一图形。
face_wrap()
:封装型,本质上是1维,为节省空间封装成二维
face_grid()
:网格型,生成一个二维的面板由两个独立的部分组成,,面板的行和列可以通过变量来定义
facet_wrap()
使用这个参数设置一长串面板二维排列,更加节省空间
可以通过 ncol
, nrow
, as.table
, dir
等参数设置排列。
如下例:
library(ggplot2)
## 从mpg数据集中取一个子集mpg2
mpg2 <- subset(mpg, cyl != 5 & drv %in% c("4", "f") & class != "2seater")
base <- ggplot(mpg2, aes(displ, hwy)) +geom_blank() +xlab(NULL) +ylab(NULL)
base
## 添加分面,设置ncol或nrow(二选一即可)
base + facet_wrap(~class, ncol = 3)
## 设置as.table
base + facet_wrap(~class, ncol = 3, as.table = FALSE)
as.table
决定各个分面的排列顺序。
## 设置dir,水平或垂直排列
base + facet_wrap(~class, nrow = 3, dir = "v")
facet_grid()
网格分面,在二维网格中展示图形。
需要设定哪些变量作为分面绘图的行,哪些变量作为列,中间用 ~
短波浪线做标记。
如下例:
mpg2 <- subset(mpg, cyl != 5 & drv %in% c("4", "f") & class != "2seater")
base <- ggplot(mpg2, aes(displ, hwy)) +geom_blank() +xlab(NULL) +ylab(NULL)
## 一行多列
base + facet_grid(. ~ cyl)
## 一列多行
base + facet_grid(drv ~ .)
## 多行多列
base + facet_grid(drv ~ cyl)
依次生成下列三种:
控制标度
• scales="fixed"
: x 和 y的标度在所有分面中都相同(默认) • scales="free_x"
: x 的标度可变,y 固定 • scales="free_y"
: y 的标度可变,x 固定 • scales="free"
: x 和 y 的标度都可变
如下例:
p <- ggplot(mpg2, aes(cty, hwy)) +geom_abline() +geom_jitter(width = 0.1, height = 0.1)
## 默认各个分面标度一致
p + facet_wrap(~cyl)
## 设置分面标度可变
p + facet_wrap(~cyl, scales = "free")
依次生成下图:
固定标度可以让我们在相同的基准上对子集进行比较
自由标度可以帮助我们看到更多细节
在变量y单位、数量级不同时,单独固定x轴,不限制y轴也很常用。如下例,经济数据集:
> economics_long
# A tibble: 2,870 x 4date variable value value01<date> <fct> <dbl> <dbl>1 1967-07-01 pce 507 0 2 1967-08-01 pce 510 0.0002663 1967-09-01 pce 516 0.0007644 1967-10-01 pce 513 0.0004725 1967-11-01 pce 518 0.0009186 1967-12-01 pce 526 0.00158 7 1968-01-01 pce 532 0.00207 8 1968-02-01 pce 534 0.00230 9 1968-03-01 pce 545 0.00322
10 1968-04-01 pce 545 0.00319
# ... with 2,860 more rows
按照不同的 variable
变量来分面:
ggplot(economics_long, aes(date, value)) +geom_line() +facet_wrap(~variable, scales = "free_y", ncol = 1)
注意,使用 facet_grid()
时有个限制,因为网格分面中,每列共用一个x轴,每行共用一个y轴。所以同列的分面中必须有相同的x标度,同行的分面必须有相同的y标度。
在 facet_grid()
中,有个参数叫 space
,当 space="free"
时,每行的高度和该行的标度范围一致,这对分类标度很有用,如下例:
其中, reorder()
使得模型(model)和生产商(manufacturer)按城市油耗英里数(cty)重新排序。
mpg2 <- subset(mpg, cyl != 5 & drv %in% c("4", "f") & class != "2seater")
mpg2$model <- reorder(mpg2$model, mpg2$cty)
mpg2$manufacturer <- reorder(mpg2$manufacturer, -mpg2$cty)
ggplot(mpg2, aes(cty, model)) +geom_point() +facet_grid(manufacturer ~ ., scales = "free", space = "free") +theme(strip.text.y = element_text(angle = 0))
下图为各种不同类型的小汽车的城市油耗英里数的点数:
缺失分面变量
下面的例子中,我们设置了俩数据框,df1和df2,其中df1中有分面变量gender,而df2里没有这个变量。这是我们可以通过增加df2的图层(并且把它放在前面,要不就盖住df1的数据点了),让df2中的数据出现在每个分面中。
df1 <- data.frame(x = 1:3, y = 1:3, gender = c("f", "f", "m"))
df2 <- data.frame(x = 2, y = 2)
ggplot(df1, aes(x, y)) +
## 先写df2的数据,设置个颜色和大小加以区分geom_point(data = df2, colour = "red", size = 5) +
## 这里默认的就是主函数中的映射geom_point() +facet_wrap(~gender)
分组和分面(Grouping vs. Facetting)
通过调整颜色、形状等图形属性可以来分组,分面则是另一种分组方法。这是两种绘图技巧,而根据子集相对位置的不同,两种技巧各有优缺。
在组间重叠严重时,分面:每个组都在单独的面板中,相隔比较远,组间无重叠。
比较组间细微差别时,使用图形属性
如下例,创建一些随机数组(x, y),然后我们先用 z
颜色分组:
df <- data.frame(x = rnorm(120, c(0, 2, 4)),y = rnorm(120, c(1, 2, 1)),z = letters[1:3]
)
ggplot(df, aes(x, y)) +geom_point(aes(colour = z))
如果我们用 z
分面:
ggplot(df, aes(x, y)) +geom_point() +facet_wrap(~z)
下面这个例子在一幅图中既分面,还算出了每组的平均值,又标明了颜色。
首先要先加载两个没用过的包(因为用到了其中的函数),我在网上看了两个小教程,大概了解一下他们是干啥的:
magrittr包:R语言高效的管道操作magrittr(http://blog.fens.me/r-magrittr/)
dplyr包:R语言数据处理利器——dplyr简介(http://www.cnblogs.com/big-face/p/4863001.html)
安装后加载
library(magrittr)
library(dplyr)
library(ggplot2)
创建随机数的数据框 df
,
df <- data.frame(x = rnorm(120, c(0, 2, 4)),y = rnorm(120, c(1, 2, 1)),z = letters[1:3]
)
创建新的数据框 df_sum
,这里用到一个管道操作符 %>%
,
摘抄一段相关说明:magrittr包被定义为一个高效的管道操作工具包,通过管道的连接方式,让数据或表达式的传递更高效,使用操作符
%>%
,可以直接把数据传递给下一个函数调用或表达式。magrittr包的主要目标有2个,第一是减少代码开发时间,提高代码的可读性和维护性;第二是让你的代码更短,再短,短短短…
group_by()
用于对数据集按照给定变量分组,返回分组后的数据集。对返回后的数据集使用以上介绍的函数时,会自动的对分组数据操作。
df_sum <- df %>%group_by(z) %>%summarise(x = mean(x), y = mean(y)) %>%rename(z2 = z)
生成均值数据集:
> df_sum
# A tibble: 3 x 3z2 x y<fct> <dbl> <dbl>
1 a 0.0875 0.934
2 b 1.91 1.99
3 c 4.05 0.993
然后创建散点分面图,第一个图层是基本散点图,第二个是通过数据处理后生成的均值数据集,并设置颜色等图形属性,最后按照 z
分面:
ggplot(df, aes(x, y)) +geom_point() +geom_point(data = df_sum, aes(colour = z2), size = 4) +facet_wrap(~z)
生成图片:
或者还有一种方法,就是把分面和颜色结合起来:
还是上面的随机数数据集df,用 dplyr
数据包中的 select()
参数,选择子数据集, -z
是指除去 z
。
df <- data.frame(x = rnorm(120, c(0, 2, 4)),y = rnorm(120, c(1, 2, 1)),z = letters[1:3]
)
df2 <- dplyr::select(df, -z)
ggplot(df, aes(x, y)) +geom_point(data = df2, colour = "grey70") +geom_point(aes(colour = z)) +facet_wrap(~z)
出图:
连续变量
连续变量也可以用来分面,我们需要先给变量规定区间,转变成离散型:
cut_interval(x,n)
:把数据分割成n和相同长度的部分cut_width(x,width)
:按宽度分cut_number(x,n=10)
:将数据划分为n个相同数目点的部分,每个分面上点数相同
(x代表数据集)
如下例,设置三种分面方法:
library(ggplot2)
mpg2 <- subset(mpg, cyl != 5 & drv %in% c("4", "f") & class != "2seater")
# Bins of width 1
mpg2$disp_w <- cut_width(mpg2$displ, 1)
# Six bins of equal length
mpg2$disp_i <- cut_interval(mpg2$displ, 6)
# Six bins containing equal numbers of points
mpg2$disp_n <- cut_number(mpg2$displ, 6)
plot <- ggplot(mpg2, aes(cty, hwy)) +geom_point() +labs(x = NULL, y = NULL)
plot + facet_wrap(~disp_w, nrow = 1)
plot + facet_wrap(~disp_i, nrow = 1)
plot + facet_wrap(~disp_n, nrow = 1)
7.3 坐标系(Coordinate Systems)
坐标系是将两种位置标度结合在一起的二维定位系统
主要有俩功能:
将两个位置图形属性(位置1、位置2;例如x, y)结合起来在图形中形成二维方位系统
配合方面:绘制坐标轴和面板背景。标度控制坐标轴的数值,映射到图形上的位置,然后通过坐标系将他们绘制出来。
具体说来,可以分为线性坐标系和非线性坐标系
线性坐标系:
coord_cartesian()
:即默认笛卡尔坐标系coord_flip()
:x轴y轴互换后的笛卡尔坐标系coord_fixed()
:具有固定长宽比的笛卡尔坐标系
非线性坐标系:
coord_map()
/coord_quickmap()
: 地图投影coord_polar()
: 极坐标coord_trans()
: 变换后的笛卡尔坐标系
7.4 线性坐标系
详细看看三种线性坐标系函数怎么使用
设定坐标轴取值范围
coord_cartesian()
函数有两个重要的参数 xlim
和 ylim
。用来设置x、y轴的取值范围。
有没有一种似曾相识的感觉?标度中的范围参数(参见笔记8,标度6.5)和他相似度90%以上。他不是也可以控制图形外观吗?
两者的不同之处在于范围参数的工作原理:
当设定标度范围时,超出范围的参数就被删除了
设定笛卡尔坐标系范围时,我们使用的仍是所有的数据,只不过只显示了其中的一小部分图形区域的数据而已。
base <- ggplot(mpg, aes(displ, hwy)) +geom_point() +geom_smooth()
# Full dataset
base
# Scaling to 5--7 throws away data outside that range
base + scale_x_continuous(limits = c(5, 7))
base + coord_cartesian(xlim = c(5, 7))
翻转坐标轴
如果你对y轴取值条件状态下的x值感兴趣,那我们可以通过使用 coord_filp()
调换坐标轴
举个栗子
ggplot(mpg, aes(displ, cty)) +geom_point() +geom_smooth()
# Exchanging cty and displ rotates the plot 90 degrees, but the smooth is fit to the rotated data.
ggplot(mpg, aes(cty, displ)) +geom_point() +geom_smooth()
# coord_flip() fits the smooth to the original data, and then rotates the output
ggplot(mpg, aes(displ, cty)) +geom_point() +geom_smooth() +coord_flip()
固定两轴比例
coord_fixed()
设置具有固定长宽比的笛卡尔坐标系。
7.5 非线性坐标系
与线性坐标不同,非线性坐标可以改变几何形状。例如,在极坐标中,矩形可能会变成弧形。在地图投影中,两点之间的最短路径不一定是直线。
下面的代码显示了在几个不同的坐标系中,如何渲染线条和矩形。
coord_polar()
是极坐标函数
rect <- data.frame(x = 50, y = 50)
line <- data.frame(x = c(1, 200), y = c(100, 1))
base <- ggplot(mapping = aes(x, y)) +geom_tile(data = rect, aes(width = 50, height = 50)) +geom_line(data = line) +xlab(NULL) + ylab(NULL)
base
base + coord_polar("x")
base + coord_polar("y")
除了以上三种,还有如下三种,依次是翻转、变换和固定坐标系:
base + coord_flip()
base + coord_trans(y = "log10")
base + coord_fixed()
最后我们说说变换(transformation),坐标系变换分两步,
首先,几何形状的参数变化只根据定位而变,和维度无关,例如矩形,只能先定位四个角再变换位置,将矩形转化为多边形。
其次,将每个位置转化到新的坐标系中。点无所谓,但对于线和多边形而言,就困难得多,因为新的坐标系中,直线不一定就是直线了。所以我们假定坐标系之间的变换是连续的,把直线看做无数段极端的直线,而这些直线变换后已然是直线,这个过程就是无限切割,然后再组合,即munching。
举个简单地栗子:
首先来看两点线:
df <- data.frame(r = c(0, 1), theta = c(0, 3 / 2 * pi))
ggplot(df, aes(r, theta)) +geom_line() +geom_point(size = 2, colour = "red")
第二步就是把这条直线平均分割出15个节点:
df <- data.frame(r = c(0, 1), theta = c(0, 3 / 2 * pi))
## 首先定义一个函数,产生多少个节点
interp <- function(rng, n) {seq(rng[1], rng[2], length = n)
}
## 设定一个新的数据集
munched <- data.frame(r = interp(df$r, 15),theta = interp(df$theta, 15)
)
ggplot(munched, aes(r, theta)) +geom_line() +geom_point(size = 2, colour = "red")
第三步就是转换后拼接
df <- data.frame(r = c(0, 1), theta = c(0, 3 / 2 * pi))
interp <- function(rng, n) {seq(rng[1], rng[2], length = n)
}
munched <- data.frame(r = interp(df$r, 15),theta = interp(df$theta, 15)
)
transformed <- transform(munched,x = r * sin(theta),y = r * cos(theta)
)
ggplot(transformed, aes(x, y)) +geom_path() +geom_point(size = 2, colour = "red") +coord_fixed()
参考资料:
Hadley Wickham(2016). ggplot2. Springer International Publishing. doi: 10.1007/978-3-319-24277-4
《R语言应用系列丛书·ggplot2:数据分析与图形艺术》
-------------------我是求关注的分界线--------------
更多R语言、可视化作图ggplot2包学习笔记请关注微信公众号:
猜你喜欢
10000+:肠道细菌 人体上的生命 宝宝与猫狗 梅毒狂想曲 提DNA发Nature 实验分析谁对结果影响大 Cell微生物专刊
系列教程:微生物组入门 Biostar 微生物组 宏基因组
专业技能:生信宝典 学术图表 高分文章 不可或缺的人
一文读懂:宏基因组 寄生虫益处 进化树
必备技能:提问 搜索 Endnote
文献阅读 热心肠 SemanticScholar Geenmedical
扩增子分析:图表解读 分析流程 统计绘图
16S功能预测 PICRUSt FAPROTAX Bugbase Tax4Fun
在线工具:16S预测培养基 生信绘图
科研经验:云笔记 云协作 公众号
编程模板 Shell R Perl
生物科普 生命大跃进 细胞暗战 人体奥秘
写在后面
为鼓励读者交流、快速解决科研困难,我们建立了“宏基因组”专业讨论群,目前己有国内外150+ PI,1500+ 一线科研人员加入。参与讨论,获得专业解答,欢迎分享此文至朋友圈,并扫码加主编好友带你入群,务必备注“姓名-单位-研究方向-职称/年级”。技术问题寻求帮助,首先阅读《如何优雅的提问》学习解决问题思路,仍末解决群内讨论,问题不私聊,帮助同行。
学习16S扩增子、宏基因组科研思路和分析实战,关注“宏基因组”
ggplot2笔记7:定位(分面和坐标系)相关推荐
- ggplot2笔记8:主题设置、存储导出
ggplot2绘图基础系列: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础.怎样加标签.注释 3工具箱--误差线.加权数.展示数据分布 4语法基础 5通过图层构建图像 6标 ...
- ggplot2笔记9:绘图需要的数据整理技术
本书的最后一个部分,Part III,Data Analysis.主要包括三个章节,今天先来看第九章: ggplot2绘图基础系列: 1初识ggplot2绘制几何对象 2图层的使用-基础.加标签.注释 ...
- ggplot2笔记4 语法基础
本公众号R语言和ggplot2笔记系列作品为袁志林老师学员创作,请关注今天二条袁老师组博后招聘启事. ggplot2绘图基础: 1初识ggplot2.基本用法以及如何绘制几何对象 2图层的使用--基础 ...
- R语言ggplot2可视化删除所有分面图(facet_wrap可视化的facet结果)的标签实战(Remove facet_wrap labels)
R语言ggplot2可视化删除所有分面图(facet_wrap可视化的facet结果)的标签实战(Remove facet_wrap labels) 目录
- Windows phone 8 学习笔记(8) 定位地图导航
Windows phone 8 学习笔记(8) 定位地图导航 原文:Windows phone 8 学习笔记(8) 定位地图导航 Windows phone 8 已经不使用自家的bing地图,新地图控 ...
- Windows phone 8 学习笔记(8) 定位地图导航(转)
Windows phone 8 学习笔记(8) 定位地图导航(转) Windows phone 8 已经不使用自家的bing地图,新地图控件可以指定制图模式.视图等.bing地图的定位误差比较大,在模 ...
- 考研数学如何整理错题笔记?140分学长总结的模板,拿走直接用(含错题笔记)
考研数学如何整理错题笔记?140分学长总结的模板,拿走直接用(含错题笔记) 数学错题笔记 2021<考研数学接力题典1800>勘误表(附学霸高分笔记) 2020考研初试成绩已经公布了,对于 ...
- 前台、中台、后台的定位分别是什么?
作者: Tom哥 简介:计算机研究生,校招进阿里,期间还拿过百度.华为.中兴.腾讯等6家大厂offer,P7 技术专家.出过专利,CSDN博客专家. 公众号:微观技术,分享其他地方看不到的知识与思考, ...
- ggplot2学习笔记10:分面(Facetting)详解
Chapter 7 Positioning 文章目录 Chapter 7 Positioning 7.1 介绍(Introduction) 7.2 分面(Facetting) 7.2.1 封装分面(F ...
最新文章
- Dijkstra算法的另一种证明
- 即刻—你的私人消息定制
- LiveVideoStack线上交流分享 ( 八 ) —— TCP的困境与解决方案
- 转载:如何在 SQL Server 中使用配置选项调整内存使用量
- Codeforces Round #233 (Div. 2)D. Painting The Wall 概率DP
- 第一章 计算机网络 5 分层结构/协议/接口/服务的概念 [计算机网络笔记]
- mysql中常见的几种索引
- DNS Flood Detector让DNS更安全
- 【JavaScript】新浪微博批量删除脚本
- iTop-4412 SCP 精英版 linux-4.14.12 内核移植(2)
- 蓝桥杯攻略大全 | 学习路线 | 注意事项
- linux下upupw搭建教程,UPUPW全能空间搭建----easypanel面板
- 安全卸载Mac应用程序的方法,最后一种不会产生卸载残留
- WINDOWS操作系统发展历程
- 相机标定(三)——手眼标定
- 兄弟们,我又回来了,干货太多让你们久等了
- 个人微信协议接口开发
- 1.1 NBU基本概念
- IE终于修复好了,原理是COM的问题
- java上传图片限制大小_求高手解决用java限制上传图片大小!!