作图前的数据准备工作不仅仅指原始数据的收集,还包括数据外观的整理,这些工作对后续的作图无疑十分重要。和其他作图方法相比,ggplot2的优点之一就是把数据整理融合到了作图过程中,替用户分担了数据整型的部分工作。ggplot2数据层面的操作包括映射和分面。先说映射。
1 映射的类型
前面我们已经了解到ggplot对象的data项存储了整个数据框的内容,而“映射”则确定如何使用这些数据。
ggplot2按照图形属性提供了以下可用映射类型:
- 颜色类型映射:包括 color(颜色或边框颜色)、fill(填充颜色)和 alpha(透明度)
- 形状类型映射:包括 linetype(线型)、size(点的大小或线的宽度)和 shape(形状)
- 位置类型映射:包括 x, y, xmin, xmax, ymin, ymax, xend, yend
- 特殊类型:包括两类,一类是指定数据分组和顺序的映射group和order,另一类是字符串映射。
前两种类型是经典的美学属性映射,第三类的x和y映射也常规,第四类很特别,尤其是字符串映射,很另类,其他类型的映射都可以用aes函数指定,但H.W.为字符串映射专门造了个函数:aes_string。不知道他对字符串特别关照还是实在想不出其他解决方案。
2 颜色和形状类型映射
规律性的东西简单轻松,大家都喜欢;而到处暗藏潜规则、充斥着特例的东西(比如plotrix、perl和中国社会)很杂碎很累人,当然也很让人烦躁和讨厌。ggplot2中颜色和形状这两类映射最符合台面规则的,即:把数据框的变量和图形的美学属性对应起来。
2.1 映射的过程
先看下面ggplot2的数据diamonds:
library(ggplot2) set.seed(100) d.sub <- diamonds[sample(nrow(diamonds), 500), ] head(d.sub, 4) ## carat cut color clarity depth table price x y z ## 16601 1.01 Very Good D SI1 62.1 59 6630 6.37 6.41 3.97 ## 13899 0.90 Ideal D SI1 62.4 55 5656 6.15 6.19 3.85 ## 29792 0.30 Ideal D SI1 61.6 56 709 4.34 4.30 2.66 ## 3042 0.30 Very Good G VS1 62.0 60 565 4.27 4.31 2.66
作图首先要指定x和y数据,即建立数据框变量和x/y之间的映射:
p <- ggplot(data=d.sub, aes(x=carat, y=price))
作出散点图:
theme_set(theme_bw()) p + geom_point()
如果还要建立其他映射,比如用钻石颜色(color)分类数据确定点的颜色,图形外观就会发生变化(为方便说明,先去掉图例):
p + geom_point() + aes(color=color) + theme(legend.position=c(2,2))
ggplot2映射的过程可以用plot函数作图步骤进行分解,它包含三方面的操作(不包括图形页面设置):
- 数据分组
- 设定颜色标尺
- 按颜色标尺指定每组数据的颜色
# 设定颜色标尺 levs <- levels(d.sub$color) cl <- rainbow(length(levs)) # 页面设置 par(mar=c(3,3,0.5,0.5), mgp=c(1.5, 0.5, 0), bg="white") plot(d.sub$carat, d.sub$price, type='n', xlab="carat", ylab="price") i <- 1 for(lev in levs){ # 数据分组 datax <- d.sub[d.sub$color==lev, ] # 作图并指定数据点颜色 points(datax$carat, datax$price, pch=20, col=cl[i]) i <- i + 1 }
上面对数据的分组只设定了一个变量,如果增加数据分组的变量,ggplot2中只需要增加映射的类型就可以了,比如在颜色分类的基础上加钻石切工(cut)进行分类:
p + geom_point() + aes(color=color, shape=cut) + theme(legend.position=c(2,2))
用plot函数处理起来要考虑的问题就多一些,可以自己试试。
2.2 映射的标尺
用plot函数作图我们得自己考虑使用什么颜色表示不同组的数据,也就是使用什么标尺(或比例尺)。ggplot2则自动应用标尺,这是一个隐含过程。标尺大体可以分为两类:
- 离散型(或枚举型)标尺。罗列出所有数据分类并将其与美学属性一一对应,处理过程包含数据分类,如上例。
- 连续型(或区间型)标尺。看下面例子:
p + geom_point() + aes(size= x*y*z ) + theme(legend.position=c(2,2))
上图中点的大小反映钻石的x*y*z值,相当于钻石的大小。用plot函数也可以实现:
cex <- d.sub[,"x"]*d.sub[,"y"]*d.sub[,"z"] cex <- cex/max(cex)*4 par(mar=c(3,3,0.5,0.5), mgp=c(1.5, 0.5, 0), bg="white") plot(d.sub$carat, d.sub$price, type='n', xlab="carat", ylab="price") points(d.sub[, "carat"], d.sub[, "price"], pch=20, cex=cex)
可以看到作图过程也需要手动建立数据和图形属性间的对应关系,但没有对数据分类。
ggplot2对映射应用的标尺可以修改,ggplot提供了一大批 scale_xxxxxxxx 类型的函数,比如 scale_color_xxxx 类型函数用户修改颜色标尺,scale_shape_xxxx 修改形状,scale_linetype_xxxx 修改线型等。按照数据的类型,这些函数还有4种基本类型:
- continuous:连续型
- discrete:离散型
- identity:和数据取值相同
- manual:手工指定
有关颜色和坐标轴标尺设定的函数较多,适应不同需要。
cls <- terrain.colors(length(levels(d.sub$color))) p + geom_point() + aes(color=color) + scale_color_manual(values=cls)
2.3 映射与图例
映射还有一个作用:产生图例。这在ggplot2也是自动的隐含过程,但在plot函数作图中是一个体力活,制作过程就不举例说明了,可以参考legend函数。
2.4 图形颜色和形状的非映射设置
除了通过映射设置几何图形的图形颜色和形状属性外,ggplot2还提供了直接设定方式。和映射方式设置不一样的是:直接设定方式不会在图例上有反映。比较下面两图:
p + geom_boxplot(aes(x=cut, fill=cut)) + scale_fill_manual(values=rep("cyan", length(levels(d.sub$cut)))) p + geom_boxplot(aes(x=cut), fill="cyan")
虽然填充色都是青色,但前者用的映射对数据进行了分组,所以会出现分组图例。注意:直接设定方法的参数名称和映射设定是一样的,但是不放在aes函数内部。
在qplot函数中如果要进行美学属性的非映射设定得用 “I” 函数,否则将被当长映射设置。
qplot(x=cut, y=price, data=d.sub, geom="boxplot", fill="cyan") qplot(x=cut, y=price, data=d.sub, geom="boxplot", fill=I("cyan"))
“I”函数表示设为固定值,如果不是在qplot函数中可以不用它。
透明度属性虽然包含在映射类型中,但一般情况下都是直接设定而非映射设定:
p + geom_point(data=diamonds, aes(alpha=carat/100)) p + geom_point(data=diamonds, alpha=0.05)
第一张图就达不到设置透明度显示点密集度的效果
3 位置类型映射
x和y映射的用法很明确,就不再罗嗦了。xmin, xmax, ymin, ymax, xend, yend这几种映射属于特殊类型,H.W.在ggplot2的说明档里面写得很清楚(赞,H.W.不仅是写R软件的高手,还是普及教育的牛人),下面就照搬他的例子简单说明一下用法。
3.1 ymin/ymax映射的用法
下面代码通过直线拟合产生了钻石切工和价格的关系数据(预测的价格和标准差)
dmod <- lm(price ~ cut, data = diamonds) cuts <- data.frame(cut = unique(diamonds$cut), predict(dmod, data.frame(cut = unique(diamonds$cut)), se = TRUE)[c 1=""se.fit")" language="("fit","][/c]) cuts ## cut fit se.fit ## 1 Ideal 3458 27.00 ## 2 Premium 4584 33.75 ## 3 Good 3929 56.59 ## 4 Very Good 3982 36.06 ## 5 Fair 4359 98.79
通过设定ymin/ymax映射,用pointrange几何类型可以直接做出带误差线的散点图,无需使用errorbar设置:
se <- ggplot(cuts, aes(x = cut, y = fit, ymin = fit - se.fit, ymax = fit + se.fit, colour = cut)) se + geom_pointrange()
当然也可以先画点再做误差线,这样思路明确些。或者做其他类型的图如柱形图:
se + geom_point() + geom_errorbar(width=0.2) se + geom_bar(stat="identity", aes(fill=cut)) + geom_errorbar(width=0.2)
min/ymax可以用来改变几何类型的坐标轴范围,但 这不是标准用法 ,最简单的是用ylim函数:
se + geom_point(aes(ymin = 3000, ymax = 4800)) + geom_errorbar(width=0.2) se + geom_point() + geom_errorbar(width=0.2) + ylim(3000,4800) # 或者用: scale_y_continuous(limits=c(3000,5000))
但以上方法都不适用于柱形图,得用下面的方法,具体原因以后章节再说:
se + geom_bar(stat="identity", aes(fill=cut)) + geom_errorbar(width=0.2) + coord_cartesian(ylim=c(3000,4800))
如果几何类型的设置参数中就包含位置类型映射,情况是很不一样的。所谓“太极”,有点道理:
px <- ggplot(mtcars, aes(wt, mpg)) + geom_point() px + annotate("rect", xmin = 2, xmax = 3.5, ymin = 2, ymax = 25, fill = "dark grey", alpha = .5) library(grid) px + geom_segment(aes(x = 5, y = 30, xend = 3.5, yend = 25), arrow = arrow(length = unit(0.5, "cm")))
4 特殊类型映射
在ggplot2作图过程中,映射的处理在先于其他绘图步骤,也先于统计运算。颜色和形状类型的映射会对数据进行分组,统计运算使用的也是分组后的数据:
ggplot(d.sub, aes(x=carat, y=price, color=cut)) + geom_point() + geom_smooth(method="lm", se=FALSE)
上面图中平滑曲线的统计处理是按cut进行分类后的数据进行的,分别作出了每一类数据的曲线。但如果要按分组前的数据做统计,就得把数据设为一个整体组;如果要按其他分组方式进行统计,也可以灵活设置:
ggplot(d.sub, aes(x=carat, y=price, color=cut)) + geom_point() + geom_smooth(aes(group=1), method="lm", se=FALSE) ggplot(d.sub, aes(x=carat, y=price, color=cut)) + geom_point() + geom_smooth(aes(group=color, linetype=color), method="lm", se=FALSE, color="black")
特殊类型映射有特殊应用。曲线图和柱形图对于x轴数据类型的要求是不一样的,曲线图要用连续型数据,而柱形图要用因子型(或离散型)数据,这两类图形如果不经特殊处理就不能放在一起。group映射可以轻松搞定它:
se + geom_bar(stat="identity", aes(fill=cut)) + geom_errorbar(width=0.2) + coord_cartesian(ylim=c(3000,4800)) + geom_line(aes(group=1), color="black")
order映射用于改变数据类型的排序。注意是在图层中的排列顺序而不是图例的先后顺序。看下面图形颜色的差别:
p + geom_point(aes(color=cut, order=cut)) library(plyr) # 使用desc函数 p + geom_point(aes(color=cut, order=desc(cut)))
aes_string太过另类,不说了。
5 SessionInfo
sessionInfo() ## R version 3.1.0 (2014-04-10) ## Platform: x86_64-pc-linux-gnu (64-bit) ## ## locale: ## [1] LC_CTYPE=zh_CN.UTF-8 LC_NUMERIC=C ## [3] LC_TIME=zh_CN.UTF-8 LC_COLLATE=zh_CN.UTF-8 ## [5] LC_MONETARY=zh_CN.UTF-8 LC_MESSAGES=zh_CN.UTF-8 ## [7] LC_PAPER=zh_CN.UTF-8 LC_NAME=C ## [9] LC_ADDRESS=C LC_TELEPHONE=C ## [11] LC_MEASUREMENT=zh_CN.UTF-8 LC_IDENTIFICATION=C ## ## attached base packages: ## [1] grid tcltk stats graphics grDevices utils datasets ## [8] methods base ## ## other attached packages: ## [1] plyr_1.8.1 ggplot2_0.9.3.1 zblog_0.1.0 knitr_1.5 ## ## loaded via a namespace (and not attached): ## [1] colorspace_1.2-4 digest_0.6.4 evaluate_0.5.3 formatR_0.10 ## [5] gtable_0.1.2 highr_0.3 labeling_0.2 MASS_7.3-31 ## [9] munsell_0.4.2 proto_0.3-10 Rcpp_0.11.1 reshape2_1.2.2 ## [13] scales_0.2.4 stringr_0.6.2 tools_3.1.0
原文来自:http://blog.csdn.net/u014801157/article/details/24372505