1.ggplot2发展历程
ggplot2是Hadley在爱荷华州立大学博士期间的作品,也是他博士论文的主题之一,实际上ggplot2还有个前身ggplot,但后来废弃了,某种程度上这也是Hadley写软件的特 征,熟悉他的人就知道这不是他第一个“2”版本的包了(还有reshape2)。带2的包和原来的包在语法上会有很大的改动,基本上不兼容。尽管如此,他的R代码风格在R社区可谓独树一帜,尤其是他的代码结构很好,可读性很高,ggplot2是R代码抽象的一个杰作。读者若感兴趣,可以在GitHub网站上浏览他的包:。在用法方面,ggplot2也开创了一种奇特而绝妙的语法,那就是加号:一幅图形从背后的设计来说,是若干图形语法的叠加,从外在的代码来看,也是若干R对象的相加。这一点精妙尽管只是ggplot2系统的很小一部分,但我个人认为没有任何程序语言可比拟,它对作为泛型函数的加号的扩展只能用两个字形容:绝了。
2.作者简介
Hadley Wickham,RStudio首席科学家,美国莱斯大学统计学助理教授,毕业于爱荷华州立大学统计系。Hadley是R社区最活跃的人之一,代码风格独树一帜,致力于开发用于数据处理、分析、成像的工具,截至2012年已经开发了超过30个高质量的R软件包,比如ggplot2, lubridate,plyr, reshape2, stringr, httr等。
3.qplot(quick plot)快速绘图函数
本节会使用ggplot2包内带的汽车测试数据(mpg)来举个例子,变量包括发动机容量(displ)、高速公路上的每加仑行驶里数(hwy)、汽缸数目(cyl)等。
ggplot2 中最简单的绘图方式是利用qplot() 函数,即快速绘图函数。格式为:
qplot(x, y = NULL, ..., data, facets = NULL, margins = FALSE, geom = 'auto', xlim = c(NA, NA), ylim = c(NA, NA), log = '', main = NULL, xlab = deparse(substitute(x)), ylab = deparse(substitute(y)), asp = NA, stat = NULL, position = NULL)quickplot(x, y = NULL, ..., data, facets = NULL, margins = FALSE, geom = 'auto', xlim = c(NA, NA), ylim = c(NA, NA), log = '', main = NULL, xlab = deparse(substitute(x)), ylab = deparse(substitute(y)), asp = NA, stat = NULL, position = NULL)
参数含义:
选项
描述
alpha
元素重叠的alpha透明度,数值为0(完全透明)到1(完全不透明)间的分数
color、shape、size、fill
把变量的水平与符号颜色、形状或大小联系起来。对于直线图, color将把线条颜色与变量水平联系起来,对于密度图和箱线图, fill将把填充颜色与变量联系起来。图例将会被自动绘制
data
指定一个数据框
facets
指定条件变量,创建一个栅栏图。表达式如rowvar ~ colvar(示例见图16-10)。为创建一个基于单条件变量的栅栏图,可用rowvar ~ .或. ~ colvar
geom
设定定义图形类型的几何形状。 geom选项是一个单条目或多条目的字符型向量,包括 'point' 、 'smooth' 、 'boxplot' 、 'line' 、 'histogram' 、'density' 、 'bar' 和'jitter'
main、sub
字符向量,设定标题和副标题
method、formula
若geom = 'smooth' ,则会默认添加一条平滑拟合曲线和置信区间。 当观测数大于1000时,便需要调用更高效的平滑拟合算法。方法包括回归lm、广义可加模型gam、稳健回归rlm。 formula参数指定拟合的形式例如,要添加简单的回归曲线,则设定geom = 'smooth', method = 'lm',formula = y ~ x。将表达式改为y ~ poly(x, 2) 将生成二次拟合。注意表达式使用的是字母x和y,而不是变量的名称对于method = 'gam' ,一定要记得加载mgcv包。对于method = 'rml' ,则需加载MASS包
x、y
指定摆放在水平轴和竖直轴的变量。对于单变量图形(如直方图),则省略y
xlab、ylab
字符向量,设定横轴和纵轴标签
xlim、ylim
二元素数值型向量,分别指定横轴和纵轴的最小值和最大值
stat
废弃
asp
The y/x aspect ratio ,y/x宽高比
log
Which variables to log transform ('x', 'y', or 'xy'),指定对数变换的变量
margins
See facet_grid: display marginal facets?用于facet-grid:是否显示边界分面
# 使用默认设置画散点图qplot(mpg, wt, data = mtcars)
# 根据cyl属性使用颜色标记qplot(mpg, wt, data = mtcars, colour = cyl)
# 根据cyl属性使用尺寸大小表示qplot(mpg, wt, data = mtcars, size = cyl)
# 使用vs~am分为4个组 分别画散点图qplot(mpg, wt, data = mtcars, facets = vs ~ am)
qplot(1:10, rnorm(10), colour = runif(10))
mod mtcars)qplot(resid(mod), fitted(mod))
f function() { a 1:10 b 2 qplot(a, b)}f()
# 指定颜色qplot(mpg, wt, data = mtcars, colour = I('red'))
# 频数图
qplot(mpg, data = mtcars)
qplot(y = mpg, data = mtcars)
# Use different geoms使用不同的几何对象qplot(mpg, wt, data = mtcars, geom = 'path')# 路径qplot(factor(cyl), wt, data = mtcars, geom = c('boxplot', 'jitter'))# 箱线图+抖动qplot(mpg, data = mtcars, geom = 'dotplot')# 点图
4.ggplot2基本元素
图层(Layer):如果你用过photoshop,那么对于图层一定不会陌生。一个图层好比是 一张玻璃纸,包含有各种图形元素,你可以分别建立图层然后叠放在一起,组合成图形的最终效果。图层可以允许用户一步步的构建图形,方便单独对图层进行修 改、增加统计量、甚至改动数据。
标度(Scale):标度是一种函数,它控制了数学空间到图形元素空间的映射。一组连续数据可以映射到X轴坐标,也可以映射到一组连续的渐变色彩。一组分类数据可以映射成为不同的形状,也可以映射成为不同的大小。
坐标系统(Coordinate):坐标系统控制了图形的坐标轴并影响所有图形元素,最常用的是直角坐标轴,坐标轴可以进行变换以满足不同的需要,如对数坐标。其它可选的还有极坐标轴。
位面(Facet):很多时候需要将数据按某种方法分组,分别进行绘图。位面就是控制分组绘图的方法和排列形式。
数据(data):需要可视化的数据。
映射(mapping):一系列将数据中变量对应到图形属性。
几何对象(geom):代表在图中实际看到的图形元素,如点、线、多边形等。
统计变换(stats):是对数据进行某种汇总。例如:将数据分组计数以创建直方图,或是将一个二维的关系用线性模型进行解释。统计变换是可选个的,但通常非常有用。
4.1ggplot绘图函数格式
ggplot(data = NULL, mapping = aes(), ..., environment = parent.frame())
4.2数据(data)和映射(mapping)
以钻石数据集为例,由于数据量大,随机选取一个子集来画图:
require(ggplot2)data(diamonds)set.seed(42)newDiamonds 1000), ]head(newDiamonds)## carat cut color clarity depth table price x y z## 49345 0.71 Very Good H SI1 62.5 60 2096 5.68 5.75 3.57## 50545 0.79 Premium H SI1 61.8 59 2275 5.97 5.91 3.67## 15434 1.03 Ideal F SI1 62.4 57 6178 6.48 6.44 4.03## 44792 0.50 Ideal E VS2 62.2 54 1624 5.08 5.11 3.17## 34614 0.27 Ideal E VS1 61.6 56 470 4.14 4.17 2.56## 27998 0.30 Premium E VS2 61.7 58 658 4.32 4.34 2.67
查看summary:
summary(newDiamonds)## carat cut color clarity depth table ## Min. :0.2200 Fair : 28 D:121 SI1 :258 Min. :55.20 Min. :50.10 ## 1st Qu.:0.4000 Good : 88 E:186 VS2 :231 1st Qu.:61.00 1st Qu.:56.00 ## Median :0.7100 Very Good:227 F:164 SI2 :175 Median :61.80 Median :57.00 ## Mean :0.8187 Premium :257 G:216 VS1 :141 Mean :61.71 Mean :57.43 ## 3rd Qu.:1.0700 Ideal :400 H:154 VVS2 : 91 3rd Qu.:62.50 3rd Qu.:59.00 ## Max. :2.6600 I:106 VVS1 : 67 Max. :72.20 Max. :65.00 ## J: 53 (Other): 37 ## price x y z ## Min. : 342.0 Min. :3.850 Min. :3.840 Min. :2.330 ## 1st Qu.: 989.5 1st Qu.:4.740 1st Qu.:4.758 1st Qu.:2.920 ## Median : 2595.0 Median :5.750 Median :5.775 Median :3.550 ## Mean : 4110.5 Mean :5.787 Mean :5.791 Mean :3.572 ## 3rd Qu.: 5495.2 3rd Qu.:6.600 3rd Qu.:6.610 3rd Qu.:4.070 ## Max. :18795.0 Max. :8.830 Max. :8.870 Max. :5.580
绘图实际上是将数据中的变量映射到图形属性上,将克拉(carat)数映射为x轴变量,价格(price)映射为y轴变量,如下所示:
g price))# 查看变量g的数据head(g$data)## carat cut color clarity depth table price x y z## 49345 0.71 Very Good H SI1 62.5 60 2096 5.68 5.75 3.57## 50545 0.79 Premium H SI1 61.8 59 2275 5.97 5.91 3.67## 15434 1.03 Ideal F SI1 62.4 57 6178 6.48 6.44 4.03## 44792 0.50 Ideal E VS2 62.2 54 1624 5.08 5.11 3.17## 34614 0.27 Ideal E VS1 61.6 56 470 4.14 4.17 2.56## 27998 0.30 Premium E VS2 61.7 58 658 4.32 4.34 2.67# 查看变量g的映射g$mapping## * x -> carat## * y -> price
以上代码将数据映射到XY坐标轴上,然后需要告诉ggplot2,这些数据要映射成什么样的几何对象,下面以散点为例:
# 设定几何对象为散点geom_point()g geom_point()# 显示图层g
如果想要将属性切工(cut)映射到形状属性,可以通过下面的代码实现:
g cut))g +geom_point()
将钻石的颜色(color)映射颜色属性:
g color))g+geom_point()
4.3几何对象(geom Geometric)
4.1中各种属性映射由ggplot函数执行,只需要加一个图层(用+连接),使用geom_point()告诉ggplot要画散点,于是所有的属性都映射到散点上。geom_point()就是几何对象散点的映射,ggplot2提供了各种几何对象的映射,如geom_histogram用于直方图,geom_bar用于柱状图,geom_boxplot用于箱线图等等,见下表(省略geom_):
查看可用几何对象:
ls('package:ggplot2', pattern='^geom_.+')## [1] 'geom_abline' 'geom_area' 'geom_bar' 'geom_bin2d' ## [5] 'geom_blank' 'geom_boxplot' 'geom_contour' 'geom_count' ## [9] 'geom_crossbar' 'geom_curve' 'geom_density' 'geom_density_2d'## [13] 'geom_density2d' 'geom_dotplot' 'geom_errorbar' 'geom_errorbarh' ## [17] 'geom_freqpoly' 'geom_hex' 'geom_histogram' 'geom_hline' ## [21] 'geom_jitter' 'geom_label' 'geom_line' 'geom_linerange' ## [25] 'geom_map' 'geom_path' 'geom_point' 'geom_pointrange'## [29] 'geom_polygon' 'geom_qq' 'geom_quantile' 'geom_raster' ## [33] 'geom_rect' 'geom_ribbon' 'geom_rug' 'geom_segment' ## [37] 'geom_smooth' 'geom_spoke' 'geom_step' 'geom_text' ## [41] 'geom_tile' 'geom_violin' 'geom_vline'
不同的几何对象,要求的属性会有些不同,这些属性也可以在几何对象映射时提供,比如上一图,也可以用以下语法来画:
g ggplot(newDiamonds) g+geom_point(aes(x=carat, y=price, shape=cut, colour=color))
由于ggplot2支持图层,通常,把不同的图层中共用的映射提供给ggplot函数,而某一几何对象才需要的映射参数提供给geom_xxx函数。
下面介绍各种结合对象的画法:
4.3.1直方图histogram
ggplot2使用图层将各种图形元素逐步添加组合,从而形成最终结果。第一层必须是原始数据层,其中data参数控制数据来源,注意数据形式只能是数据框格式。aes参数控制了对哪些变量进行图形映射,以及映射方式,aes是Aesthetic的缩写。
直方图最容易,提供一个x变量,画出数据的分布。
ggplot(newDiamonds) + geom_histogram(aes(x = price))
同样可以根据另外的变量给它填充颜色,比如按不同的切工:
ggplot(newDiamonds) + geom_histogram(aes(x = price,fill = cut))
也可以将其分开,side-by-side地画直方图。
ggplot(newDiamonds) + geom_histogram(aes(x = price,fill = cut), position='dodge')
还可以使用position='fill',按照相对比例来画。
查看信息:
g ggplot(newDiamonds) g 'dodge')print(g)summary(g)## data: carat, cut, color, clarity, depth, table, price, x, y, z [1000x10]## faceting: facet_null() ## -----------------------------------## mapping: x = price, fill = cut ## geom_bar: na.rm = FALSE## stat_bin: binwidth = NULL, bins = NULL, na.rm = FALSE, pad = FALSE## position_dodge
上面的信息告诉我们,g对象含有两层(由--------分界),第一层数据层描述了变量和映射方式,第二层是直方图对象(geom_histogram),geom表示几何对象,它是ggplot中重要的图层控制对象,因为它负责图形渲染的类型。geom_histogram是图形渲染类型的一种,其它类型可参见官网。
每个geom对象都需要有数据输入,数据可以从第一层中自动读取,也可以在aes参数中直接设置。而且每个geom还默认搭配某种统计变换(stat),geom_histogram的默认统计变换是stat_bin。它负责对数据进行分组计数。
下面我们尝试两种更为复杂的直方图,首先将数据按照year这个变量划分为两组,用不同的颜色绘制直方图,而且用频率而非计数来刻画Y轴,并添加密度曲线。
g mpg,aes(hwy))g 'identity',alpha = 0.5,aes(y = ..density..,fill = factor(year)))g 'line',position = 'identity',aes(colour = factor(year)),adjust = 0.5)print(g)
alpha:透明度调节;position: fill:填充色,此处是根据因子年份来选择颜色进行填充,一般使用与条形图,fill后面跟着的是一个变量,且是一个分类变量,得到的结果是颜色会根据分类不同使用不同颜色;colour:边框色或线颜色;position = 'dodge'将同类条形图并排放着,(dodge英文意思是闪躲回避的意思,这样记它的作用会比较快)
将两年分开表示:
g mpg,aes(hwy))g 'identity',alpha = 0.5,aes(y = ..density..,fill = factor(year)))g 'line',position = 'identity',aes(colour = factor(year)),adjust = 0.5)g 1)print(g)
下面逐步变化直方图:
ggplot(data=iris,aes(x=Sepal.Length))+ geom_histogram()
上面的图形不够生动,我们可以调整一些3参数,使之变得不一样:
ggplot(iris,aes(x=Sepal.Length))+ geom_histogram(binwidth=0.1, # 设置组距 fill='skyblue', # 设置填充色 colour='black') # 设置边框色
直方图加密度曲线:直方图的作用主要是展现分组计数和分布特性,因为考查一个样本是否符合某个分布在传统统计学中有着重要的意义。不过有另一种方法也可以展现数据的分布,即核密度估计曲线。简单来说就是根据数据估算一条可以代表其分布的密度曲线。我们可以将直方图和密度曲线重叠显示。
ggplot(iris,aes(x=Sepal.Length)) + geom_histogram(aes(y=..density..), fill='skyblue', color='black') + stat_density(geom='line',color='black', linetype=2,adjust=2)
密度曲线:adjust参数和窗宽参数类似,它将会控制密度曲线的细节表现能力。我们来尝试用不同的参数绘制多条密度曲线。可见参数越小曲线越为波动灵敏,adjuct负责控制这个参数。
ggplot(iris,aes(x=Sepal.Length)) + geom_histogram(aes(y=..density..), # 注意要将y设为相对频数 fill='gray60', color='gray') + stat_density(geom='line',color='blue',linetype=1,adjust=0.5)+ stat_density(geom='line',color='red',linetype=2,adjust=1)+ stat_density(geom='line',color='green',linetype=3,adjust=2)
密度曲线还方便对不同数据进行比较,例如我们要对iris中三种不同花的Sepal.Length分布进行比较,可以像下面一样:
ggplot(iris,aes(x=Sepal.Length,fill=Species)) + geom_density(alpha=0.5,color='red')
4.3.2条形图或柱形图bar
柱状图两个要素,一个是分类变量,一个是数目,也就是柱子的高度。数目在这里不用提供,因为ggplot2会通过x变量计算各个分类的数目。
mpg数据集中各车型所比例,以及在这些车型中各年份所占的比例。
class factor(mpg$year)p class,fill=year))+ geom_bar(color='black')print(p)
条形图位置调整,也就是前面总出现的position参数的设置值:位置调整(Position adjustments)是针对同一图层内元素的位置进行微调的方法。它包括五种设置,分别是stack(堆叠)、dodge(躲开,闪避)、fill(填充)、identity(密度)、jitter(抖动)。
仍使用mpg数据集,其中用到的变量是class,即生产汽车的类型,以及year生产年份。下面的条形图是将各类型的汽车数量进行汇集,并以年份作为分组变量。我们首先载入扩展包,然后用频数表对数据进行大致的了解,最后绘制了四种条形图。
library(ggplot2)with(mpg,table(class,year))## year## class 1999 2008## 2seater 2 3## compact 25 22## midsize 20 21## minivan 6 5## pickup 16 17## subcompact 19 16## suv 29 33g class,fill=factor(year)))summary(g)## data: manufacturer, model, displ, year, cyl, trans, drv, cty, hwy, fl, class## [234x11]## mapping: x = class, fill = factor(year)## faceting: facet_null()g + geom_bar(position='dodge')+labs(x='class',y='count',title = 'dodge闪避')
#也可以写成position_dodge()g + geom_bar(position='stack')+labs(x='class',y='count',title = 'stack堆叠')
#也可以写成position_stack()g + geom_bar(position='fill')+labs(x='class',y='count',title = 'fill填充')
#也可以写成position_fill()g + geom_bar(position='identity',alpha=0.3) + labs(x='class',y='count',title = 'identity密度')
#也可以写成position_identity()
可以看到dodge方式是将不同年份的数据并列放置;stack方式是将不同年份数据推叠放置,这也是geom_bar和geom_histogram的默认处理方式;fill方式和stack类似,但Y轴不再是计数,而是以百分比显示;identity方式是不做任何改变直接显示出来,所以需要设置透明度才能看得清楚。注意:position同样适用于直方图
柱状图和直方图的区别:
柱状图和直方图是很像的,直方图把连续型的数据按照一个个等长的分区(bin)来切分,然后计数,画柱状图。而柱状图是分类数据,按类别计数。我们可以用前面直方图的参数来画side-by-side的柱状图,填充颜色或者按比例画图,它们是高度一致的。
柱状图是用来表示计数数据的,但在生物界却被经常拿来表示均值,加上误差来表示数据分布,这可以通常图层来实现,我将在图层一节中给出实例。
更多参考如下官网:
本公众号精彩历史文章:
04:如何在R软件中求一致性指数( Harrell'concordance index:C-index)?
05:Nomogram 绘制原理及R&SAS实现.
06 : Lasso方法简要介绍及其在回归分析中的应用
07 : 最优模型选择中的交叉验证(Cross validation)方法
08 : 用R语言进行分位数回归(Quantile Regression)
09 : 样本数据中异常值(Outliers)检测方法及SPSS & R实现
10 : 原始数据中几类缺失值(Missing Data)的SPSS及R处理方法
11 : [Survival analysis] Kaplan-Meier法之SPSS实现
12 : [Survival analysis] COX比例风险回归模型在SPSS中的实现
13 : 用R绘制地图:以疾病流行趋势为例
14 : 数据挖掘方法:聚类分析简要介绍 及SPSS&R实现
15 : 医学研究中的Logistic回归分析及R实现
16 : 常用的非参数检验(Nonparametric Tests)总结
17 : 高中生都能看懂的最小二乘法原理
18 : R语言中可实现的常用统计假设检验总结(侧重时间序列)
19 : 如何根据样本例数、均数、标准差进行T-Test和ANOVA
20 : 统计学中自由度的理解和应用
21 : ROC和AUC介绍以及如何计算AUC
22 : 支持向量机SVM介绍及R实现
23 : SPSS如何做主成分分析?
24 : Bootstrap再抽样方法简介
25 : 定量测量结果的一致性评价及 Bland-Altman 法的应用
26 : 使用R绘制热图及网络图
27 : 几种常用的双坐标轴图形绘制
28 : 遗失的艺术—诺谟图(Nomogram)
29 : Nomogram 绘制原理及R&SAS实现(二)
30 : WOE:信用评分卡模型中的变量离散化方法
31 : 结构方程模型(SEM)简介及教程下载
32 : 重复测量的多因素方差分析SPSS实现操作过程