7.1 简介
# 本章的主题是图形的定位
# 主要讲解 布局分面和坐标系两个问题
# 由四个部分组成
# 1,位置调整 调整每个图层中出现重叠的对象的位置,4.8节有过介绍
# 2,位置标度 控制数据到图形中位置的映射,6.4.2小节有过介绍
# 3,分面 在一个页面上自动摆放多幅图形的技法,参见7.2节
# 4,坐标系 通过控制两个独立的位置标度来生成一个2维的坐标系。最常见的是笛卡尔坐标系。
7.2 分面
# ggplot2 提供两种分面类型:网格型(facet_grid)和 封装型(facet_wrap)
# 网格分面生成的是一个2维的面板网络
# 封装分面生成一个1维的面板条块,然后再封装到2维中
# 制作mpg2 子集
library(ggplot2)
mpg2 <- subset(mpg,cyl !=5 & drv %in% c("4","f"))
head(mpg2)
# A tibble: 6 x 14
manufacturer model displ year cyl trans drv cty hwy fl class displ_ww displ_wn displ_nn
<chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr> <fct> <fct> <fct>
1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact [1,2] [1.6,2.42] [1.6,2]
2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact [1,2] [1.6,2.42] [1.6,2]
3 audi a4 2 2008 4 manual(m6) f 20 31 p compact [1,2] [1.6,2.42] [1.6,2]
4 audi a4 2 2008 4 auto(av) f 21 30 p compact [1,2] [1.6,2.42] [1.6,2]
5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compact (2,3] (2.42,3.23] (2.5,3]
6 audi a4 2.8 1999 6 manual(m5) f 18 26 p compact (2,3] (2.42,3.23] (2.5,3]
7.2.1 网格分面
# 1,不进行分面
# 不使用函数facet_grid或使用命令facet_null()
# 和 qplot(cty,hwy,data = mpg2) 效果一样
# 2,一行多列 格式:".~a"
qplot(cty,hwy,data = mpg2) + facet_grid(.~cyl)
# 3,一列多行 格式:"a~."
qplot(cty,data = mpg2,geom = "histogram",binwidth =2) + facet_grid(cyl~.)
# 4,多行多列 格式:"a~b"
qplot(cty,hwy,data = mpg2) + facet_grid(drv~cyl)
# 边际图
# 展示行或列的汇总图
# 可以使用参数margins来绘制
p <- qplot(displ,hwy,data = mpg2) + geom_smooth(method = "lm",se = F)
p
p + facet_grid(cyl~drv)
p + facet_grid(cyl~drv,margins = T)
qplot(displ,hwy,data = mpg2) + geom_smooth(aes(colour = drv),method = "lm",se = F) + facet_grid(cyl~drv,margins = T)
7.2.2 封装分面
# facet_wrap()
# 展示了每10年电影平均评分的分布情况
library(plyr)
library(ggplot2movies)
head(movies)
movies$decade <- round_any(movies$year,10,floor)
qplot(rating,..density..,data = subset(movies,decade > 1890),
geom = "histogram",binwidth = 0.5) +
facet_wrap(~ decade,ncol = 6)
7.2.3 标度控制
# 调整参数scales来控制面板的位置标度是(固定)还是(允许变化)
# scales = "fixed" x和y的标度再所有面板中都相同
# scales = "free" x和y的标度再每个面板都可以变化
# scales = "free_x" x的标度可变,y的尺度固定
# scales = "free_y" y的标度可变,x的尺度固定
p <- qplot(cty,hwy,data = mpg)
p + facet_wrap(~cyl)
p + facet_wrap(~cyl,scales = "free")
# 固定标度,在相同的基准上对子集进行比较
# 自由标度,帮助我们发现更多细节,展示不同量纲的时间序列时非常有用
# 自由标度示例
library(reshape2)
em <- melt(economics,id = "date")
head(em)
qplot(date,value,data = em,geom = "line",group = variable) + facet_grid(variable ~ .,scale = "free_y")
# facet_grid有一个额外限制:同列的面板必须有相同的x标度,同行的面板必须有相同的y标度。
# 因为网格分面中,每列都共用一个x轴,每行都共用一个y轴
# facet_grid 还有一个额外参数space,值可为“free”或“fixed”
# 设置为free时,使得所有面板的标度比例相同,看示例:
7.2.4 分面变量缺失
# 对一个含有多个数据集的图形使用分面,而其中一个数据集缺失了分面变量
# ggplot2会将 缺失的分面变量按包含该分面变量所有的值来处理
7.2.5 分组与分面
# 分组:通过调整图形属性(比如颜色,形状或大小)
# 分面:依据子集相对位置的不同分面,两者各有优缺点
# 分面,每个组别都在单独的面板中,无重叠,但组间的细微差别难以发现
# 分组,容易重叠,不过细微差别容易被发现
# 准备数据
xmaj <- c(0.3,0.5,1,3,5)
xmin <- as.vector(outer(1:10,10^c(-1,0)))
xmin
ymaj <- c (500,1000,5000,10000)
ymin <- as.vector(outer(1:10,10^c(2,3,4)))
ymin
# 使用diamonds数据集示例
dplot <- ggplot(subset(diamonds,color %in% c("D","E","G","J")),aes(carat,price,colour = color)) +
scale_x_log10(breaks = xmaj,labels= xmaj,minor = xmin) +
scale_y_log10(breaks = ymaj,labels= ymaj,minor = ymin) +
scale_colour_hue(limits = levels(diamonds$color)) +
theme(legend.position = "none")
dplot + geom_point()
dplot + geom_point() + facet_grid(.~ color)
# 使用回归线,查看各分组的距离
dplot + geom_smooth(method = lm,se = F,fullrange = T)
dplot + geom_smooth(method = lm,se = F,fullrange = T) + facet_grid(.~color)
7.2.6 并列与分面
# 分面可以绘制出与图形并列类似的效果
# 主要区别在于标注方式,请看示例:
ggplot(diamonds,aes(x=color)) + geom_bar(aes(fill = cut),position = "dodge")
qplot(cut,data = diamonds,geom = "bar",fill = cut) + facet_grid(.~color) +
theme(axis.text.x = element_text(angle = 90,hjust =1,size = 8,colour = "grey50"))
# 当两个变量的因子水平完全交叉,而部分变量组合缺失时,分面实用的多
# 它可以控制分割方式是局部的(scales = "free_x",space = "free") 还是全局的(scales = "fixed")
mpg4 <- subset(mpg,manufacturer %in% c("audi","volkswagen","jeep"))
mpg4$manufacturer <- as.character(mpg4$manufacturer)
mpg4$model <- as.character(mpg4$model)
base <- ggplot(mpg4,aes(fill = model)) + geom_bar(position = "dodge") + theme(legend.position = "none")
base + aes(x = model) + facet_grid(. ~ manufacturer)
last_plot() + facet_grid(.~manufacturer,scales = "free_x",space = "free")
base +aes(x = manufacturer)
# 总之,图形是选择分面还是并列,要视两变量间的关系而定
# 1,水平完全交叉:分面和并列基本等同
# 2,水平几乎交叉:当存在非结构性的缺失组合时,分面图形非常有用
# 3,水平无交叉:标度自由的分面会对每个有较高水平的组别分配充足的作图空间,并对每个条目进行标注
7.2.7 连续型变量
# 对连续型变量进行分面,首先要将其转换为离散型,有三种方法
# 1,将数据划分为n个长度相同的部分 cut_interval(x,n = 10)控制划分数目
# 2,cut_interval(x,length = 1) 控制每个部分的长度
# 3,将数据划分为n个有相同数目的部分 cut_number(x,n = 10)
mpg2$displ_ww <- cut_interval(mpg2$displ,length = 1)
mpg2$displ_wn <- cut_interval(mpg2$displ,n = 6)
mpg2$displ_nn <- cut_number(mpg2$displ,n = 6)
head(mpg2)
plot <- qplot(cty,hwy,data = mpg2) +labs(x = NULL,y = NULL)
plot + facet_wrap(~displ_ww,nrow = 1)
plot + facet_wrap(~displ_wn,nrow = 1)
plot + facet_wrap(~displ_nn,nrow = 1)
7.3 坐标系
# 坐标系是将两种位置标度结合在一起组成的2维定位系统
# ggplot包含了6种不同的坐标系
# 1,cartesian 笛卡尔坐标系
# 2,equal 同尺度笛卡尔
# 3,flip 翻转的笛卡尔
# 4,trans 变换的笛卡尔
# 5,map 地图射影
# 6,polar 极坐标系
# 命名规则: coord_加上坐标系名字
7.3.1 变换
# 与数据变换和标度变换不同,坐标系变换将改变图形的几何形状
# 坐标系的变换分为两步
# 首先,几何形状的参数变换只依据定位
# 第二步,将每个位置转化到新的坐标系中
# 点的转化,在任何坐标系中都是一个点
# 线和多边形切割为许多小的线段后再进行变换,称为:“分割再组合”
# 小的直线,每个都有两个端点,再将这些点转化到新的坐标系中并重新连接
7.3.2 统计量
# 准确来说,原来的统计变换(stat) 使用的统计方法都依赖坐标系的选择。
# 许多统计方法都不是源自非笛卡尔坐标系的
# 因此ggplot2仍是在笛卡尔坐标系中进行计算
# 虽然不够严格,但结果一般也非常接近真实情况
7.3.3 笛卡尔坐标系
# 有四种基于笛卡尔的坐标系
# coord_cartesian,coord_equal,coord_flip,coord_trans
# 它们之间有许多共同之处
7.3.3.1 设置范围
# coord_cartesian 有两个参数 xlim和ylim
# 标度章节中也有这两个参数,但工作原理不同
# 设定标度范围时,任何超出此范围的数据都会被删除
# 设定笛卡尔坐标系的范围时,使用的仍是所有数据,只不过展示一小片图形区域
(p <- qplot(disp,wt,data = mtcars) + geom_smooth())
p + scale_x_continuous(limits = c(325,500))
p + coord_cartesian(xlim = c(325,500))
# 标度的范围设置 会对数据取子集,然后重新拟合曲线
7.3.3.2 坐标轴翻转
# 大多数统计量和几何形状都假定 我们对x条件下的y值感兴趣
# 假如你也对y值条件下的x值感兴趣(或仅仅想将图形翻转90度)
# 就可以使用coord_flip调换x和y轴
qplot(displ,cty,data = mpg) + geom_smooth()
qplot(cty,displ,data = mpg) + geom_smooth()
qplot(cty,displ,data = mpg) + geom_smooth() + coord_flip()
7.3.3.3 变换
# 与范围设置一样,标度层面和坐标层面都可以进行数据变换
# coord_trans 有x和y两个参数,都是字符串,称作变换器
# 标度层面的变换发生在统计量计算之前,不会改变对象的几何形状
# 坐标系层面的变换发生在统计量计算之后,会影响几何形状
qplot(carat,price,data = diamonds,log = "xy") + geom_smooth(method = lm)
library(scales)
last_plot() + coord_trans(x = exp_trans(10),y = exp_trans(10))
7.3.3.4 相同标度
# coord_equal保证了x轴和y轴有相同的标度
# 默认值设定的是 1:1
# 可以通过修改参数ratio来更改两者的尺度比例
7.3.4 非笛卡尔坐标系
# 有两种:极坐标和地图投影
# 利用极坐标生成 饼图、玫瑰图、雷达图等
(pie <- ggplot(mtcars,aes(x = factor(1),fill = factor(cyl))) + geom_bar(width = 1))
pie + coord_polar(theta = "y")
pie + coord_polar()
# 地图投影
# 依赖于mapproj包
# 参考coord_map()文档