ggplot2作图详解2:ggplot图形对象

评论9,185

前面我们使用qplot函数对ggplot2做图的方法进行了初步的了解,并比较了qplot和plot函数的用法。从最终得到的结果(图形)来看,除了外观不同外好像qplot函数和plot函数并没有什么本质的差别。这其实是一个骗局!

1 图形对象

我们知道,R语言基本做图方法都是通过函数完成的(如果不了解请参考本博客《散点图》一文),这些函数直接在输出设备上执行一些列操作得到图形。很多函数没有返回值,即使有返回值也不会反映绘图操作的整个过程。但ggplot2不一样,它用图形对象存储做图的细节,通过输出图形对象获得图形。一行一行地运行下面代码可以发现这一点:

library(ggplot2)
theme_set(theme_bw())
x <- 1:100
y <- rnorm(100)
p1 <- plot(x, y)
p2 <- qplot(x, y)

ggplot2作图详解2:ggplot图形对象-图片1

很显然执行最后一行代码不会得到想要的图形。下面再看看 p1 和 p2 分别是什么:

class(p1)
## [1] "NULL"
class(p2)
## [1] "gg"     "ggplot"
typeof(p2)
## [1] "list"
str(p2)
## List of 9
##  $ data       :'data.frame': 0 obs. of  0 variables
##  $ layers     :List of 1
##   ..$ :Classes 'proto', 'environment'  
##  $ scales     :Reference class 'Scales' [package "ggplot2"] with 1 fields
##   ..$ scales: list()
##   ..and 21 methods, of which 9 are possibly relevant:
##   ..  add, clone, find, get_scales, has_scale, initialize, input, n,
##   ..  non_position_scales
##  $ mapping    :List of 2
##   ..$ x: symbol x
##   ..$ y: symbol y
##  $ theme      : list()
##  $ coordinates:List of 1
##   ..$ limits:List of 2
##   .. ..$ x: NULL
##   .. ..$ y: NULL
##   ..- attr(*, "class")= chr [1:2] "cartesian" "coord"
##  $ facet      :List of 1
##   ..$ shrink: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "null" "facet"
##  $ plot_env   : 
##  $ labels     :List of 2
##   ..$ x: chr "x"
##   ..$ y: chr "y"
##  - attr(*, "class")= chr [1:2] "gg" "ggplot"

plot函数的返回值p1的class属性为NULL(空),而qplot函数的返回值p2的calss属性有两个“gg” 和 “ggplot”,其本质是长度为9的列表对象。打印这个对象就会得到图形:

print(p2)

ggplot2作图详解2:ggplot图形对象-图片2

 

qplot函数的作用是产生一个ggplot对象,但获得ggplot对象的更一般方法是使用对象类型的同名函数ggplot。它的用法是:

# 非运行代码
ggplot(df, aes(x, y, <other aesthetics>))
ggplot(df)
ggplot()

ggplot函数用于初始化一个ggplot对象,即使不指定任何做图相关的内容,它的结构也是完整的:

length(p2)
## [1] 9
length(ggplot())
## [1] 9

2 ggplot图形对象组成

ggplot图形对象是由9个元素组成的列表,这点已经清楚。元素的名称为:

names(p2)
## [1] "data"        "layers"      "scales"      "mapping"     "theme"      
## [6] "coordinates" "facet"       "plot_env"    "labels"

但是单从图形对象的结构上没办法理解ggplot2做图的过程和细节,所以还得了解一点相关的理论。ggplot2是Wilkinson做图理论 Grammer of Graphics 的R语言实现。太高深了,不知道从哪开始,还是从ggplot图形列表对象的元素组成做一点简单了解吧。

2.1 数据 data

似乎就是数据。但是如果试图查看上面p2对象的数据:

p2$data
## data frame with 0 columns and 0 rows

是空的。但如果使用qplot函数时指定了data,情况就不一样了:

p3 <- qplot(carat, price, data=diamonds, color=cut, shape=cut)
head(p3$data, 3)
##   carat     cut color clarity depth table price    x    y    z
## 1  0.23   Ideal     E     SI2  61.5    55   326 3.95 3.98 2.43
## 2  0.21 Premium     E     SI1  59.8    61   326 3.89 3.84 2.31
## 3  0.23    Good     E     VS1  56.9    65   327 4.05 4.07 2.31
nrow(p3$data)
## [1] 53940

列表对象的data元素存储了整个diamnods数据框的数据。用ggplot函数可以单独指定data项:

p4 <- ggplot(diamonds)
head(p4$data, 3)
##   carat     cut color clarity depth table price    x    y    z
## 1  0.23   Ideal     E     SI2  61.5    55   326 3.95 3.98 2.43
## 2  0.21 Premium     E     SI1  59.8    61   326 3.89 3.84 2.31
## 3  0.23    Good     E     VS1  56.9    65   327 4.05 4.07 2.31

2.2 映射 mapping

ggplot对象的data项存储了整个数据框的内容,而“映射”则确定如何使用这些数据。在ggplot2中,图形的可视属性如形状、颜色、透明度等称为美学属性(或艺术属性),确定数据与美学属性之间对应关系的过程称为映射,通常使用aes函数完成(qplot函数中使用参数设置映射):

str(p3$mapping)
## List of 4
##  $ colour: symbol cut
##  $ shape : symbol cut
##  $ x     : symbol carat
##  $ y     : symbol price
str(p4$mapping)
##  list()
p4 <- p4 + aes(x=carat, y=price, color=color, shape=cut)
str(p4$mapping)
## List of 4
##  $ x     : symbol carat
##  $ y     : symbol price
##  $ colour: symbol color
##  $ shape : symbol cut
p4 <- p4 + aes(x=carat, y=price, color=cut, shape=cut)
str(p4$mapping)
## List of 4
##  $ x     : symbol carat
##  $ y     : symbol price
##  $ colour: symbol cut
##  $ shape : symbol cut

需要说明的是,上面第三行代码使用了加号,这是ggplot2为ggplot对象定义的运算方法,表示设置ggplot对象中对应的内容。

2.3 图层 layers

2.3.1 图层组成

在ggplot的列表结构里面看不到我们指定的图形类型参数。这些设置被分派到layers里面了:

p3$layers
## [[1]]
## geom_point:  
## stat_identity:  
## position_identity: (width = NULL, height = NULL)

一个图层包含了至少3个东西(数据和映射当然必需,另算):geom、stat和position

  • 几何类型 geom:是数据在图上的展示形式,即点、线、面等。在ggplot2里面有很多预定义的几何类型。
  • 统计类型 stat:是对数据所应用的统计类型/方法。上面的p2和p3对象我们并没有指定统计类型,但是自动获得了identity,因为ggplot2为每一种几何类型指定了一种默认的统计类型,反之亦然。所以如果仅指定geom或stat中的一个,另外一个会自动获取。
  • 位置 position:几何对象在图像上的位置调整,这也有默认设定。

不指定几何类型或统计类型的ggplot对象的图层是空列表,即没有图层,也不能输出图像:

p4$layers
## list()
print(p4)
## Error: No layers in plot

也就是说,指定了几何类型或统计类型,图层就会产生:

(p4 + geom_point())$layers
## [[1]]
## geom_point: na.rm = FALSE 
## stat_identity:  
## position_identity: (width = NULL, height = NULL)
(p4 + stat_identity())$layers
## [[1]]
## geom_point:  
## stat_identity: width = NULL, height = NULL 
## position_identity: (width = NULL, height = NULL)

为什么图层说“至少”包含3个内容呢?如果你把整个图层的内容转成列表结构显示以下就会发现更多:

as.list((p4 + geom_point())$layers[[1]])
## $mapping
## NULL
## 
## $geom_params
## $geom_params$na.rm
## [1] FALSE
## 
## 
## $stat_params
## named list()
## 
## $stat
## stat_identity: 
## 
## $inherit.aes
## [1] TRUE
## 
## $geom
## geom_point: 
## 
## $position
## position_identity: (width = NULL, height = NULL)
## 
## $subset
## NULL
## 
## $data
## list()
## attr(,"class")
## [1] "waiver"
## 
## $show_guide
## [1] NA

2.3.2 图层加法

从图层的结构可以看到它在ggplot对象中是一个多重列表,如果对ggplot对象做图层加法运算,是增加图层而不是替换图层:

(p4 + geom_point() + geom_line())$layers
## [[1]]
## geom_point: na.rm = FALSE 
## stat_identity:  
## position_identity: (width = NULL, height = NULL)
## 
## [[2]]
## geom_line:  
## stat_identity:  
## position_identity: (width = NULL, height = NULL)

2.3.3 图层顺序

ggplot2按“层”做图,所以图层的顺序对于图形的表现会有影响,如果几何对象有叠加,那么后面图层的对象会覆盖前面图层的对象。下面只是调换了两个图层的顺序,但由于数据点是相同的,所以图形的颜色完全不一样:

p4 + geom_point(color="red") + geom_point(color="blue")
p4 + geom_point(color="blue") + geom_point(color="red")

ggplot2作图详解2:ggplot图形对象-图片3ggplot2作图详解2:ggplot图形对象-图片4

 

2.4 标尺 scales

这是ggplot2中比较复杂的一个概念,从ggplot对象中能获取的信息不多:

p4$scales
## Reference class object of class "Scales"
## Field "scales":
## list()

在ggplot2中,一个标尺就是一个函数,它使用一系列参数将我们的数据(如钻石价格、克拉)转成计算机能够识别的数据(如像素、颜色值),然后展示在图像上。使用标尺对数据进行处理的过程称为缩放(scaling)。坐标的产生和图形美学属性的处理都需要使用标尺对数据进行缩放。这个过程比较复杂,尤其是美学属性与数据的关联,因为和美学属性相关的数据不仅有连续型还有离散型,多组数据之间还要相互关照。但这些过程我们都可以不管,ggplot2也替我们做了。

标尺是函数,它的反函数用于产生坐标刻度标签和图表的图例等,这样我们才能把图形外观、位置等信息和数据对应起来。

2.5 坐标 coordinates

这都知道,用于确定采用的坐标系统和坐标轴的范围。

str(p4$coordinates)
## List of 1
##  $ limits:List of 2
##   ..$ x: NULL
##   ..$ y: NULL
##  - attr(*, "class")= chr [1:2] "cartesian" "coord"

2.6 主题 theme

标题文字(字体、字号、颜色)、图形边框和底纹等跟数据无关的一些图形元素的设置都可以归到“主题”这一类。ggplot2提供了4个成套主题:theme_gray(), theme_bw() , theme_minimal() 和 theme_classic()。其中theme_gray()为默认主题,灰背景;后两个是0.9.3版才增加的。

p5 <- p4 + geom_point(color="blue")
p5 + theme_gray() + ggtitle("theme_gray()")
p5 + theme_bw() + ggtitle("theme_bw()")
p5 + theme_minimal() + ggtitle("theme_minimal()")
p5 + theme_classic() + ggtitle("theme_classic()")

ggplot2作图详解2:ggplot图形对象-图片5ggplot2作图详解2:ggplot图形对象-图片6

ggplot2作图详解2:ggplot图形对象-图片7ggplot2作图详解2:ggplot图形对象-图片8

 

2.7 分面 facet:

一页多图,跟图层好像没有直接关系。以后再说。

2.8 标签 labels:

str(p4$labels)
## List of 4
##  $ x     : chr "carat"
##  $ y     : chr "price"
##  $ colour: chr "cut"
##  $ shape : chr "cut"

3 ggplot2做图过程

如果E文水平可以,下载 Hadley Wickham 写的《ggplot2: Elegant Graphics for Data Analysis》一书来看看(到处都有)。理论性太强,太高深,不敢乱说。

4 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] tcltk     stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
## [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] grid_3.1.0       gtable_0.1.2     highr_0.3        labeling_0.2    
##  [9] MASS_7.3-31      munsell_0.4.2    plyr_1.8.1       proto_0.3-10    
## [13] Rcpp_0.11.1      reshape2_1.2.2   scales_0.2.4     stringr_0.6.2   
## [17] tools_3.1.0

原文来自:http://blog.csdn.net/u014801157/article/details/24372503

发表评论

匿名网友