定位
简介
定位由四个部分组成
- 位置调整 调整每个图层中出现重叠的对象的位置。
- 位置标度 控制数据到图形中位置的映射。常用的映射是线性和对数变换。
- 分面 一页多图,也通常被称作小联号图(small multiples)。
- 坐标系 通过控制两个独立的位置标度来生成一个2维坐标系。
分面
ggplot2提供两种分面类型:网格型(face_grid)和封装型(facet_wrap),分别类似于R基础图形中的coplot
布局和lattice
的面板布局。
#mpg的子集,简化为3种气缸(4,6,8)和两种驱动轮(4,f)。
mpg2 <- subset(mpg,cyl != 5 & drv %in% c("4","f"))
- 一行多列:
".~a"
qplot(cty,hwy,data = mpg2) +
facet_grid(.~cyl)
* 一列多行:b ~ .
。
qplot(cty,data = mpg2,geom = "histogram",binwidth=2) +
facet_grid(cyl ~ .)
* 多行多列:a ~ b
。
qplot(cty,hwy,data = mpg2) +
facet_grid(drv ~ cyl)
- 多个变量的多个水平在行或者列上:
.~a+b
或a+b~.
。
综上,变量在某行或某列一起出现时,图形只会展示数据中出现的变量组合。而变量在行和列都出现时,图形将展示所有的变量组合,包括在原始数据中没有出现的组合,不过这也可能会导致出现空白面板。
边际图
设定margins = TRUE
可展示一行或者列的总和,或者如margins = c("sex","age")
,列出你要展示的边际图的变量名称。另外,也可以使用grand_row
或grand_col
来分别生成所有行或所有列的边际图。
p <- qplot(displ,hwy,data = mpg2)+
geom_smooth(method = "lm",se=F)
p + facet_grid(cyl ~ drv)
p + facet_grid(cyl ~ drv, margins = T)
无边际图
列边际图和行边际图分别展示了所有的驱动轮和所有的气缸,右下角的分面则暂时了整个数据集的情况。随着气缸数增加,燃油经济性能下降;相比前轮驱动的汽车,四轮驱动汽车有大致相同的排量,但燃油经济性较低。
p <- qplot(displ,hwy,data = mpg2)+
geom_smooth(aes(colour = drv),method = "lm",se=F)
p + facet_grid(cyl ~ drv, margins = T)
对每个驱动轮类型添加彩色平滑线。
封装分面
facet_wrap
并不是用两个或更多的变量来生成一个2维网格,而是先生成一个长的面板条块(由任意数目的变量生成),然后将它封装在2维中。也可以通过设置ncol
,nrow
来更新设置。
qplot(depth, ..density.. , data = diamonds,geom = "histogram",binwidth=0.5)+
facet_wrap(~cut)
标度控制
对于两种分面,可以通过调整阐述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)
p1 <- p + facet_wrap(~cyl)
p2 <- p + facet_wrap(~cyl,scales = "free")
固定标度可以让我们在相同的基准上对子集进行比较,观察在哪些地方各子集有相似的总体模式。而自由标度可以帮助我们发现更多细节,它在展示不同量纲的时间序列时非常有用。
brary(reshape2)
#用reshape2中的melt包将原始数据框按照时间重组,生成,时间,变量,数值数据框。
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”
、“free_x”
、“free_y”
或“fixed”
。当space
设定为free
时,每列(行)的宽度(高度)与该列(行)的标度范围成比例。这将使得所有面板的标度比例相同:每个面板中的1cm都映射为相同的数据范围。例如,若面板a有2个单位的范围,面板b有4个单位的范围,那么三分之一的空间将分配给a,其余的分配给b。
#reorder()可使模型(model)和生产商(manuafacturer)按城市油耗(cty)重新排序。
mpg3 <- within(mpg2,{model <- reorder(model,cty)
manufacturer <- reorder(manufacturer,-cty)})
models <- qplot(cty,model,data = mpg3)
p1 <- models
p2 <- models + facet_grid(manufacturer ~ ., scales = "free",
space = "free")+
theme(strip.text.y = element_text(angle = 360))
分组与分面
此处分组表示通过调整图形属性来分组。
xmaj <- c(0.3,0.5,1,3,5)
#outer 向量的外积,vector将矩阵转化为向量。
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) +
scale_y_log10(breaks = ymaj,labels = ymaj, minor = ymin) +
scale_colour_hue(limits = levels(diamonds$color)) + #颜色的定义域
theme(legend.position = "none")
p1 <- dplot + geom_point()
p2 <- dplot + geom_point() + facet_grid(.~color)
p3 <- dplot + geom_smooth(method = lm, se=F,fullrange = T)
p4 <- dplot + geom_smooth(method = lm, se=F,fullrange = T)+facet_grid(.~color)
数据子集若有不同的尺度范围,各个面板中标度可以作相应调整。
并列与分面
并列和分面绘制的图形看起来非常相似,它们主要的区别在于标注方式:分面图形在上方有颜色的标注,同时下面有切工的标注,而并列图形在下方有颜色标注,切工却没有清晰标注出来。
p1 <- ggplot(data = diamonds,aes(color))+
geom_bar(aes(fill=cut),position="dodge")
p2 <- 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"))
并列(上) vs 分面(下)
当两个变量的因子水平几乎完全交叉,而部分变量组合缺失时,两种绘图方式也就会有所不同。此时,并列图形的用处不大,因为它只是对条形图做局部地分割,没有任何标签。而分面就实用的多,他能控制分割方式是局部的(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")
p1<-base + aes(x=model)+
facet_grid(.~manufacturer)
p2<-last_plot()+
facet_grid(.~manufacturer,scales = "free_x",space = "free")
p3<-base + aes(x=manufacturer)
对于嵌套型数据,分面(上,中)的优势相比并列(下)是明显的,它能控制图形并进行标注。此例中,上图不是很使用,但对于几乎交叉的数据非常有用,比如缺失了一个水平组合的情况。
连续型变量
连续型变量进行分面,首先必须将其离散化。
- 将数据分为n个长度相同的部分:用
cut_interval(x,n=10)
控制划分数目,或用cut_interval(x,length=1)
控制每个部分的长度。 - 将数据分为n个有相同数据点的部分:
cut_number(x,n=10)
。但需要注意每个部分的标度范围是不同的。
从上至下:面板长度为1;每个面板等长;每个面板包含数目的点相同。
坐标系
- 位置1和位置2:x,y;角度和半径;维度和经度。
- 配合分面,坐标系将绘出坐标轴和面板背景。
ggplot2中可用的坐标系
名字 | 描述 |
---|---|
cartesian | 笛卡尔坐标系 |
equal | 同尺度笛卡尔坐标系 |
flip | 翻转的笛卡尔坐标系 |
trans | 变换的笛卡尔坐标系 |
map | 地图射影 |
polar | 极坐标系 |
变换
与数据变换和标度变换不同,坐标系变换将改变图形的几何形状。
- 几何形状的参数变化只依据定位(位置),而不是定位(位置)和维度(高度和宽度)。
- 假定坐标系之间的变换是连续的,即所有的极短的直线变换后仍是很短的直线,这样,就可以将线“切割再组合”(munching)。
笛卡尔坐标系
设置范围
设定坐标系范围就好比用放大镜观看图形一样。
p <- qplot(disp,wt,data = mtcars)+geom_smooth()
p1 <- p + scale_x_continuous(limits = c(325,500))
p2 <- p + coord_cartesian(xlim = c(325,500))
d <- ggplot(diamonds,aes(carat,price)) +
stat_bin2d(bins = 25,colour = "grey70")+
theme(legend.position = "none")
p1 <- d + scale_x_continuous(limits = c(0,2))
p2 <- d + coord_cartesian(xlim = c(0,2))
(左)完整的数据集;(中)x的标度范围设置为(325,500);(右)坐标系x轴范围设置为(325,500)
左)完整的数据集;(中)x的标度范围设置为(0,2);(右)坐标系x轴范围设置为(0,2)
坐标轴翻转
(左)散点图和相应的平滑曲线,x轴代表发动机排量(displ),y代表城市油耗(cty)。(中)互换x和y,平滑曲线拟合的是旋转后的变量。(右)coord_flip 拟合初始数据,然后再翻转输出结果,就变成了以y为条件变量刻画x的曲线了。
变换
p1 <- qplot(carat,price,data = diamonds,log = "xy")+
geom_smooth(method = "lm")
library(scales)
p2 <- last_plot()+coord_trans(x=exp_trans(10),y=exp_trans(10))
(左)克拉与价格对数变换,直线为回归曲线: log ( y ) = a + b × log ( x ) \log(y)=a+b×\log(x) log(y)=a+b×log(x);(右)将前面的图变换回去,线性趋势变成指数形式, y = k × c x y = k × c^x y=k×cx。
相同标度
coord_equal
保证了x轴和y轴有相同的标度:x轴上和y轴上的1cm代表相同的数据波动范围,默认1:1,我们可以通过修改参数ratio
来更改两者的尺度比例。
非笛卡尔坐标系,地图投影
试验阶段