教材: ggplot2 数据分析与图形艺术
1. 分面
即在一个页面上自动摆放多幅图形的技法:先将数据划分为多个子集,然后将每个子集依次绘制到页面.
ggplot2提供两种分面类型:网格型(facetgrid) 和 封装型 (facet_wrap)
网格分面生成的是一个2维的面板网络,面板的行与列通过变量定义。
封装型本质是一维为了节省空间封装成2维
分面系统又两个基本参数:一个是分面变量的设置,一个是指定分面的位置标度是全局还是局部。
在qplot()中可以选择分面系统。2维分面(x~y)使用 facet_grid, 1 维使用facet_wrap
分面绘图会占用大量的空间,因此本节使用mpg数据集的子集来进行展示。它有几个简单的水平:三种气缸(4,6,8)和两种驱动轮(4,f)。 子集剔除了原数据中的29辆车。
mpg2 <- subset(mpg, cyl != 5 & drv %in% c("4","f"))
2.1 网格分面
网格分面在2维网络中展示图形。输入分面表达式时,你需要设定哪些变量作为分面绘图的行,哪些作为列:
(1)不进行分面,即不使用函数facet_grid或机上命令facet_null() 此时,没有行或列被分面化,我们将得到一个单独的面板。
qplot(cty,hwy,data=mpg2)
(2)一行多列:“.~a"。 电脑屏幕通常较宽,因此这个方向最适合数据的展示。另外因为纵坐标相同,这个方向也有助于y位置的比较
qplot(cty,hwy,data=mpg2) + facet_grid(.~cyl)
(3)一列多行:”b~“。横坐标轴相同,利于x比较,尤其是对数据分布的比较
(4) 多行多列:”a~b"。我们通常将因子水平数目最大的变量按列放
qplot(cty,hwy,data=mpg2)+facet_grid(drv~cyl)
(5)多个变量的多个水平在行或者列上:~a+b 或 a+b ~. 。 一般说来这种方法不怎么实用,除非变量因子水平个数比较少,或电脑屏幕很宽,或需要生成一个瘦长的海报。
边际图
切割图形就好比创建一个列联表。展示每个单元格的值以及边际和。
设定margins = TRUE 可以展示所有的边际图,或者如margins=c("sex","age"),列出你想要展示的边际图的变量名称。另外你也可以使用grand_row 或 grand_col来分别生成所有行或列的边际图。
下面对每个驱动轮类型添加彩色的平滑线
2.2 封装分面
facet_wrap不是用两个或更多的变量来生成一个2维网格,而是先生成一个长面板,再封装
e.g facet_wrap(~decade, ncol = 6)
2.3 标度控制
scales = "fixed" /"free"
scales = "free_x" / "free_y"
library(reshape2)
em <- melt(economics,id = "date")
qplot(date,value,data = em, geom = "line", group = variable)+
facet_grid(variable ~ ., scale = "free_y")
使用网格分面时facet_grid 有一个额外的限制:同列必须有相同x,同行同y。
facet_grid 还有一个额外的参数space,值可为”free" 或 “fixed”。当space设定为free时,每行/列与其标度范围成比例
mpg3 <- within(mpg2,{model <- reorder(model,cty)
manufacturer <- reorder(manufacturer, -cty)})
models <- qplot(cty,model,data=mpg3)
models
models + facet_grid(manufacturer ~ ., scales="free", space="free")+
theme(strip.text.y = element_text())
2.4 分面变量缺失
例如,你想对疾病的空间分布按性别进行分面绘图,但是一个新添加的地图图层不包含性别变量,这时该如何处理呢? ggplot2会按照你所期望的那样,给每个面板都添加地图,此时缺失的分面变量按包含该分面变量的所有值来处理。
2.5 分组与分面
xmaj <- c(0.3,0.5,1,3,5)
xmin <- as.vector(outer(1:10,10^c(-1,0)))
ymaj <- c(500,1000,5000,10000)
ymin <- as.vector(outer(1:10,10^c(2,3,4)))
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)+ ##minor控制刻度
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)
2.6 并列与分面
原书qplot,position=dodge似乎已经被弃用,这里直接用ggplot
ggplot(aes(x=color,fill=cut),data=diamonds)+
geom_bar(position="dodge2")
ggplot(aes(x=cut,fill=cut),data=diamonds)+
geom_bar(position="dodge")+facet_grid(.~color)+
theme(axis.text.x=element_text(angle=90,hjust=1,size=8,colour = "grey50"))
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)
2.7 连续型变量
对连续型变量进行分面,首先需要将其变换为离散型,有三种方法:
(1) 将数据分为n个长度相同的部分:用cutinterval(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)
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)
3. 坐标系
coord_cartesian()
equal 同尺度笛卡尔坐标系
flip 翻转的笛卡尔坐标系
trans 变换的笛卡尔坐标系
map 地图射影
polar 极坐标系
笛卡尔坐标系
coord_cartesian()有两个参数xlim,ylim,和limit不同,当设定笛卡尔坐标系的范围时,我们使用的仍是所有的数据,只不过只展示一小片图形区域。好比用放大镜管卡图形一样
p <- qplot(disp,wt,data=mtcars)+geom_smooth()
p + scale_x_continuous(limits = c(325,500))
p+coord_cartesian(xlim=c(325,500))
d <- ggplot(diamonds,aes(carat,price))+
stat_bin2d(bins=25,colour="grey70")+
theme(legend.position = "none")
d + scale_x_continuous(limits=c(0,2))
d+coord_cartesian(xlim=c(0,2))