2017年10月19日

ggplot2

ggplot2是一个用来绘制统计图形的R语言包

  • 基于《Grammar of Graphics》(Wilkinson,2005)一书的图形语法支持,采用图层的设计方式,从原始图层开始,首先绘制原始数据,然后不断添加图形注释和统计汇总结果,逻辑清晰,功能强大
  • 精心挑选了一系列预设图形,可以快速绘出高质量图形
  • 如果对格式有额外要求,可以使用主题系统进行定制,不需要花费时间调整外观

安装和载入ggplot2

安装ggplot2

install.packages("ggplot2")

载入ggplot2

library(ggplot2)

数据集——diamonds

  • 约54000颗钻石的价格和质量信息,数据已经包含在ggplot2包中。
  • 数据涵盖了反映钻石质量的四“C”:克拉重量(carat)、切工(cut)、颜色(color)、净度(clarity),以及五个物理指标:深度(depth)、钻面宽度(table)、x、y、z。

读入数据

data("diamonds")
head(diamonds, 10) # tail(diamonds)
# A tibble: 10 x 10
   carat       cut color clarity depth table price     x     y     z
   <dbl>     <ord> <ord>   <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 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
 4  0.29   Premium     I     VS2  62.4    58   334  4.20  4.23  2.63
 5  0.31      Good     J     SI2  63.3    58   335  4.34  4.35  2.75
 6  0.24 Very Good     J    VVS2  62.8    57   336  3.94  3.96  2.48
 7  0.24 Very Good     I    VVS1  62.3    57   336  3.95  3.98  2.47
 8  0.26 Very Good     H     SI1  61.9    55   337  4.07  4.11  2.53
 9  0.22      Fair     E     VS2  65.1    61   337  3.87  3.78  2.49
10  0.23 Very Good     H     VS1  59.4    61   338  4.00  4.05  2.39

str(diamonds)
Classes 'tbl_df', 'tbl' and 'data.frame':   53940 obs. of  10 variables:
 $ carat  : num  0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
 $ cut    : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
 $ color  : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
 $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
 $ depth  : num  61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
 $ table  : num  55 61 65 58 58 57 57 55 61 61 ...
 $ price  : int  326 326 327 334 335 336 336 337 337 338 ...
 $ x      : num  3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
 $ y      : num  3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
 $ z      : num  2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...

summary(diamonds)
     carat               cut        color        clarity     
 Min.   :0.2000   Fair     : 1610   D: 6775   SI1    :13065  
 1st Qu.:0.4000   Good     : 4906   E: 9797   VS2    :12258  
 Median :0.7000   Very Good:12082   F: 9542   SI2    : 9194  
 Mean   :0.7979   Premium  :13791   G:11292   VS1    : 8171  
 3rd Qu.:1.0400   Ideal    :21551   H: 8304   VVS2   : 5066  
 Max.   :5.0100                     I: 5422   VVS1   : 3655  
                                    J: 2808   (Other): 2531  
     depth           table           price             x         
 Min.   :43.00   Min.   :43.00   Min.   :  326   Min.   : 0.000  
 1st Qu.:61.00   1st Qu.:56.00   1st Qu.:  950   1st Qu.: 4.710  
 Median :61.80   Median :57.00   Median : 2401   Median : 5.700  
 Mean   :61.75   Mean   :57.46   Mean   : 3933   Mean   : 5.731  
 3rd Qu.:62.50   3rd Qu.:59.00   3rd Qu.: 5324   3rd Qu.: 6.540  
 Max.   :79.00   Max.   :95.00   Max.   :18823   Max.   :10.740  
                                                                 
       y                z         
 Min.   : 0.000   Min.   : 0.000  
 1st Qu.: 4.720   1st Qu.: 2.910  
 Median : 5.710   Median : 3.530  
 Mean   : 5.735   Mean   : 3.539  
 3rd Qu.: 6.540   3rd Qu.: 4.040  
 Max.   :58.900   Max.   :31.800  
                                  

为了分析和展示的方便,选取容量为100的原始数据随机样本。

set.seed(1410)
dsmall <- diamonds[sample(nrow(diamonds), 100), ]
head(dsmall)
# A tibble: 6 x 10
  carat     cut color clarity depth table price     x     y     z
  <dbl>   <ord> <ord>   <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  1.35   Ideal     J     VS2  61.4    57  5862  7.10  7.13  4.37
2  0.30    Good     G    VVS1  64.0    57   678  4.23  4.27  2.72
3  0.75   Ideal     F     SI2  59.2    60  2248  5.87  5.92  3.49
4  0.26   Ideal     F     VS1  60.9    57   580  4.13  4.11  2.51
5  0.33 Premium     H    VVS1  61.4    59   752  4.42  4.44  2.72
6  1.52   Ideal     G    VVS1  62.4    55 15959  7.30  7.39  4.58

qplot绘图

qplot():ggplot包中的快速绘图函数。

钻石价格和重量的关系

qplot(carat, price, data = dsmall)

变量间有很强的相关关系,以及一些明显的异常值。竖直方向上有一些有趣的条纹,相关关系似乎是指数型的,对变量进行变换。

qplot(log(carat), log(price), data = dsmall)

此时关系接近线性

钻石体积和重量的关系

qplot(carat, x * y * z, data = dsmall)

钻石的密度(质量除以体积)应该是一个常数,因此体积与重量应该是线性关系,但仍存在异常点。

向重量和价格的散点图添加颜色信息

qplot(carat, price, data = dsmall, color = color)

向重量和价格的散点图添加切工信息

qplot(carat, price, data = dsmall, shape = cut)

大数据时,使用半透明的颜色减轻图形元素的重叠,0完全透明,1完全不透明,一般用分数,分母表示10次重叠后完全不透明。

qplot(carat, price, data = diamonds, alpha = I(1/10))

qplot(carat, price, data = diamonds, alpha = I(1/100))

几何对象——geom

几何对象geom描述了应该用何种对象展示数据。
通过改变几何对象geom可以画出任何一种类型的图形。
geom = point 绘制散点图,为qplot的默认设置。
geom = smooth 绘制平滑曲线图。

qplot(carat, price, data = dsmall, geom = "smooth")

利用 c() 函数将多个几何对象组成一个向量传递给geom,几何对象会按照指定的顺序进行堆叠。

qplot(carat, price, data = dsmall, geom = c("point", "smooth"))

span 调整曲线的平滑程度,取值范围从0(很不平滑)到1(很平滑)。

qplot(carat, price, data = dsmall, geom = c("point", "smooth"), 
      span = 0.8)

geom = jitter 绘制扰动点图

qplot(color, price / carat, data = diamonds, geom = "jitter")

alpha 参数改变透明图

qplot(color, price / carat, data = diamonds, geom = "jitter", 
      alpha = I(1 / 5))

qplot(color, price / carat, data = diamonds, geom = "jitter", 
      alpha = I(1 / 50))

geom = boxplot 绘制箱型图

qplot(color, price / carat, data = diamonds, geom = "boxplot")

geom = histogram 绘制直方图

qplot(carat, data = diamonds, geom = "histogram")

分组绘制直方图

qplot(carat, data = diamonds, geom = "histogram", fill = color)

binwidth 参数设定组距
xlim 参数设定x轴范围

qplot(carat, data = diamonds, geom = "histogram", binwidth = 1, 
      xlim = c(0, 3))

geom = density 绘制密度曲线图,adjust 参数控制曲线的平滑程度。

qplot(carat, data = diamonds, geom = "density")

要在不同组之间对分布进行对比,只需另外加上一个图形映射。

qplot(carat, data = diamonds, geom = "density", color = color)

条形(柱状)图

条形(柱状)图适用于离散变量的情形,采用 geom = bar 绘制。

qplot(color, data = diamonds, geom = "bar")

时间序列中的线条图和路径图

线条图和路径图常用语可视化时间序列数据。
线条图将点从左到右进行连接,路径图则按照点在数剧集中的顺序对其进行连接。
线条图的x轴一般是时间,展示了单个变量随时间变化的情况,路径图则展示了两个变量随时间联动的情况,时间反映在点的顺序上。

economics数据集包含了美国过去40年的经济数据。

str(economics)
Classes 'tbl_df', 'tbl' and 'data.frame':   574 obs. of  6 variables:
 $ date    : Date, format: "1967-07-01" "1967-08-01" ...
 $ pce     : num  507 510 516 513 518 ...
 $ pop     : int  198712 198911 199113 199311 199498 199657 199808 199920 200056 200208 ...
 $ psavert : num  12.5 12.5 11.7 12.5 12.5 12.1 11.7 12.2 11.6 12.2 ...
 $ uempmed : num  4.5 4.7 4.6 4.9 4.7 4.8 5.1 4.5 4.1 4.6 ...
 $ unemploy: int  2944 2945 2958 3143 3066 3018 2878 3001 2877 2709 ...
  • date:数据采集月份
  • pce:个人消费支出(10亿美元)
  • pop:人口数(千人)
  • psavert:个人储蓄率
  • uempmed:失业时长(星期,中位数)
  • unmeploy:失业人数(千人)

summary(economics)
      date                 pce               pop            psavert      
 Min.   :1967-07-01   Min.   :  507.4   Min.   :198712   Min.   : 1.900  
 1st Qu.:1979-06-08   1st Qu.: 1582.2   1st Qu.:224896   1st Qu.: 5.500  
 Median :1991-05-16   Median : 3953.6   Median :253060   Median : 7.700  
 Mean   :1991-05-17   Mean   : 4843.5   Mean   :257189   Mean   : 7.937  
 3rd Qu.:2003-04-23   3rd Qu.: 7667.3   3rd Qu.:290291   3rd Qu.:10.500  
 Max.   :2015-04-01   Max.   :12161.5   Max.   :320887   Max.   :17.000  
    uempmed         unemploy    
 Min.   : 4.00   Min.   : 2685  
 1st Qu.: 6.00   1st Qu.: 6284  
 Median : 7.50   Median : 7494  
 Mean   : 8.61   Mean   : 7772  
 3rd Qu.: 9.10   3rd Qu.: 8691  
 Max.   :25.20   Max.   :15352  

失业率的月变化

qplot(date, unemploy / pop, data = economics, geom = "line")

失业时长的月变化

qplot(date, uempmed, data = economics, geom = "line")

失业率和失业时长随时间的变化路径

qplot(unemploy / pop, uempmed, data = economics, 
      geom = c("point", "path"))

其他选项

qplot中还有一其他的选项用于控制图形的外观。

  • xlim,ylim:设置x轴和Y轴的显示区间,它们的取值都是一个长度为2的数值向量,例如 xlim = c(0, 20)ylim = c(0.9, 0.5)
  • log:说明哪一个坐标轴应该取对数。例如 log = "x" 表示对x轴取对数,log = "xy"表示对x轴和y轴都取对数。
  • main:图形的主标题,放置在图形的顶端,以大字号显示,参数的取值可以是一个字符串或一个表达式。
  • xlab,ylab:设置x轴和y轴的标签文字,参数的取值可以是字符串或表达式。

qplot(carat, price, data = dsmall, xlab = "Weight (carats)", 
      ylab = "Price ($)", main = "Price-weight relationship")

qplot(carat, price, data = dsmall, log = "xy")