《R语言实战》day?-第十一章:中级绘图

本章内容

本章,我们主要关注用于展示双变量间关系(二元关系)和多变量间关系(多元关系)的绘 图方法。

比如下面的例子。

 汽车里程与车重的关系是怎样的?它是否随着汽车的汽缸数目不同而变化?

 如何在一个图形中展示汽车里程、车重、排量和后轴比之间的关系?

 当展示大数据集(如10 000个观测)中的两个变量的关系时,如何处理数据点严重重叠的 情况?换句话说,当图形变成了一个大黑点时怎么办?

 如何一次性展示三个变量间的多元关系(给你一个电脑屏幕或一张纸,并且预算没有《阿 凡达》那么多)?

 如何展示一些树随时间推移的生长情况

 如何在单幅图中展示一堆变量的相关性?它又如何帮助你理解数据的结构?

 对于“泰坦尼克号”中幸存者的数据如何可视化他们的船舱等级、性别和年龄间的关 系?可以从这样的图形中得出什么样的结论?

11.1 散点图

  1. 描述x对y的二元变量关系
  2. 探究通过额外信息来增强图形表达功能
  3. 将多个散点图组合成散点图矩阵,以便同时浏览多个二元关系
  4. 回顾数据点重叠的案例,解决重叠问题
  5. 添加第三个连续变量——扩展到三维:三维散点图和气泡图

例子:添加最佳拟合曲线的散点图

attach(mtcars) 
plot(wt, mpg, 
 main="Basic Scatter plot of MPG vs. Weight", 
 xlab="Car Weight (lbs/1000)", 
 ylab="Miles Per Gallon ", pch=19) 
abline(lm(mpg~wt), col="red", lwd=2, lty=1) 
lines(lowess(wt,mpg), col="blue", lwd=2, lty=2) 

  • 汽车英里数对车重的散点图,添加了线性拟合直线和lowess拟合曲线
  • 创建了一幅基本的散点图,图形的符号①是实 心圆圈。
  • 与预期结果相同,随着车重的增加,每加仑英里数减少,虽然它们不是完美的线性关系。 abline()函数用来添加最佳拟合的线性直线
  • lowess()函数则用来添加一条平滑曲线。该平 滑曲线拟合是一种基于局部加权多项式回归的非参数方法。算法细节可参见Cleveland(1981)。

R有两个平滑曲线拟合函数:lowess()和loess()。loess()是基于lowess()表达式版 本的更新和更强大的拟合函数。这两个函数的默认值不同,因此要小心使用,不要把它 们弄混淆了。

car包中的scatterplot()函数增强了散点图的许多功能,

  • 它可以很方便地绘制散点图,并 能添加拟合曲线、边界箱线图和置信椭圆,还可以按子集绘图和交互式地识别点。
library(car) 
scatterplot(mpg ~ wt | cyl, data=mtcars, lwd=2, span=0.75, 
 main="Scatter Plot of MPG vs. Weight by # Cylinders", 
 xlab="Weight of Car (lbs/1000)", 
 ylab="Miles Per Gallon", 
 legend.plot=TRUE, 
 id.method="identify", 
 labels=row.names(mtcars), 
 boxplots="xy" 
)
  • scatterplot()函数用来绘制四缸、六缸和八缸汽车每加仑英里数对车重的图形。 表达式mpg ~ wt | cyl表示按条件绘图(即按cyl的水平分别绘制mpg和wt的关系图)。
  • 默认地,各子集会通过颜色和图形符号加以区分,并同时绘制线性拟合和平滑拟合曲线。
  • span参数控制loess曲线中的平滑量。它的参数值越大,拟合得就越好。
  • id.method选项的设定 表明可通过鼠标单击来交互式地识别数据点,直到用户选择Stop(通过图形或者背景菜单)或者 敲击Esc键。
  • labels选项的设定表明可通过点的行名称来识别点。此图中可以看到,给定Toyata Corolla和Fiat 128的车重,通常每加仑燃油可行驶得更远。
  • legend.plot选项表明在左上边界添 加图例
  • 而mpg和weight的边界箱线图可通过boxplots选项来绘制。

总之,scatterplot() 函数还有许多特性值得探究,比如本节未讨论的稳健性选项和数据集中度椭圆选项。更多细节可 参见help(scatterplot)

  • 散点图可以一次对两个定量变量间的关系进行可视化。
  • 但是如果想观察下汽车里程、车重、 排量(立方英寸)和后轴比间的二元关系,该怎么做呢?
  • 一种途径就是将六幅散点图绘制到一个 矩阵中,这便是下节即将介绍的散点图矩阵。

11.1.1 散点图矩阵

R中有很多创建散点图矩阵的实用函数。pairs()函数可以创建基础的散点图矩阵。下面的 代码生成了一个散点图矩阵,包含mpg、disp、drat和wt四个变量:

pairs(~mpg+disp+drat+wt, data=mtcars, 
 main="Basic Scatter Plot Matrix")

  • 值得注意的是,主对角线的上方和下方的六幅散点图是相同的,这也是为 了方便摆放图形的缘故。
  • 通过调整参数,可以只展示下三角或者上三角的图形。
  • 例如,选项 upper.panel = NULL将只生成下三角的图形。

car包中的scatterplotMatrix()函数也可以生成散点图矩阵,并有以下可选操作:

 以某个因子为条件绘制散点图矩阵;

 包含线性和平滑拟合曲线;

 在主对角线放置箱线图、密度图或者直方图;

 在各单元格的边界添加轴须图。

library(car) 
scatterplotMatrix(~ mpg + disp + drat + wt, data=mtcars, 
 spread=FALSE, smoother.args=list(lty=2), 
 main="Scatter Plot Matrix via car Package") 
  • 可以看到线性和平滑(loess)拟合曲线被默认添加
  • 主对角线处添加了核密 度曲线和轴须图。
  • spread = FALSE选项表示不添加展示分散度和对称信息的直线,
  • smoother.args=list(lty=2)设定平滑(loess)拟合曲线使用虚线而不是实线。

R提供了许多其他的方式来创建散点图矩阵。你可能想探索glus包中的cpars()函数, TeachingDemos包中的pairs2()函数,HH包中的xysplom()函数,ResourceSelection包中 的kepairs()函数和SMPracticals包中的pairs.mod()函数。每个包都加入了自己独特的曲 线。

11.1.2 高密度散点图:基础包中的smoothScatter()函数以及IDPmisc包中的ipairs()函数

set.seed(1234) 
n <- 10000 
c1 <- matrix(rnorm(n, mean=0, sd=.5), ncol=2) 
c2 <- matrix(rnorm(n, mean=3, sd=2), ncol=2) 
mydata <- rbind(c1, c2) 
mydata <- as.data.frame(mydata) 
names(mydata) <- c("x", "y") 

高度重合,数据点的重叠导致识别x与y间的关系变得异常困难。针对这种情况,R提供了一 些解决办法。你可以使用封箱、颜色和透明度来指明图中任意点上重叠点的数目。

smoothScatter()函数可利用核密度估计生成用颜色密度来表示点分布的散点图。

更易读

hexbin包中的hexbin()函数将二元变量的封箱放到六边形单元格中 (图形比名称更直观)

library(hexbin) 
with(mydata, { 
 bin <- hexbin(x, y, xbins=50) 
 plot(bin, main="Hexagonal Binning with 10,000 Observations") 
 })

综上可见,基础包中的smoothScatter()函数以及IDPmisc包中的ipairs()函数都可以对 大数据集创建可读性较好的散点图矩阵。通过?smoothScatter和?ipairs可获得更多的示例。

11.1.3 三维散点图

例如,假使你对汽车英里数、车重和排量间的关系感兴趣,可用scatterplot3d包中的 scatterplot3d()函数来绘制它们的关系。

scatterplot3d(x, y, z) 
  • x被绘制在水平轴上,y被绘制在竖直轴上,z被绘制在透视轴上。
library(scatterplot3d) 
attach(mtcars) 
scatterplot3d(wt, disp, mpg, 
 main="Basic 3D Scatter Plot")

satterplot3d()函数提供了许多选项,包括设置图形符号、轴、颜色、线条、网格线、突 出显示和角度等功能。

library(scatterplot3d) 
attach(mtcars) 
scatterplot3d(wt, disp, mpg, 
 pch=16, 
 highlight.3d=TRUE, 
 type="h", 
 main="3D Scatter Plot with Vertical Lines") 

  • 增强了纵深感,添加了连接点与水平面的垂直线

再添加一个回归面

library(scatterplot3d) 
attach(mtcars) 
s3d <-scatterplot3d(wt, disp, mpg, 
 pch=16, 
 highlight.3d=TRUE, 
 type="h", 
 main="3D Scatter Plot with Vertical Lines and Regression Plane") 
fit <- lm(mpg ~ wt+disp) 
s3d$plane3d(fit)

  • 图形利用多元回归方程,对通过车重和排量预测每加仑英里数进行了可视化处理。平面代表 预测值,图中的点是实际值。
  • 平面到点的垂直距离表示残差值。若点在平面之上则表明它的预测 值被低估了,而点在平面之下则表明它的预测值被高估了

11.1.4 旋转三维散点图

你可用rgl包中的plot3d()函数创建可交互的三维散点图

plot3d(x, y, z)
  • 其中x、y和z是数值型向量,代表着各个点。
  • 你还可以添加如col和size这类的选项来分别控制 点的颜色和大小。
library(rgl) 
attach(mtcars) 
plot3d(wt, disp, mpg, col="red", size=5)

你也可以使用car包中类似的函数scatter3d()

library(car) 
with(mtcars, 
 scatter3d(wt, disp, mpg)) 

  • scatter3d()函数可包含各种回归曲面,比如线性、二次、平滑和附加等类型。
  • 图形默认添 加线性平面。

11.1.5 气泡图:先创建一个二维散点图,然后用点的大小来代表第三个变量的值

我们通过三维散点图来展示三个定量变量间的关系。现在介绍另外一种思 路:先创建一个二维散点图,然后用点的大小来代表第三个变量的值。这便是气泡图(bubble plot)。

symbols()函数来创建气泡图。该函数可以在指定的(x, y)坐标上绘制圆圈图、方形 图、星形图、温度计图和箱线图。以绘制圆圈图为例:

 symbols(x, y, circle=radius) 

其中x、y和radius是需要设定的向量,分别表示x、y坐标和圆圈半径。

你可能想用面积而不是半径来表示第三个变量,那么按照圆圈半径的公式变换即 可:

symbols(x, y, circle=sqrt(z/pi))

z即第三个要绘制的变量。

attach(mtcars) 
r <- sqrt(disp/pi) 
symbols(wt, mpg, circle=r, inches=0.30, 
 fg="white", bg="lightblue", 
 main="Bubble Plot with point size proportional to displacement", 
 ylab="Miles Per Gallon", 
 xlab="Weight of Car (lbs/1000)") 
text(wt, mpg, rownames(mtcars), cex=0.6) 
detach(mtcars) 

  • 选项inches是比例因子,控制着圆圈大小(默认最大圆圈为1英寸)。
  • text()函数是可选函数,此处用来添加各个汽车的名称。
  • 从图中可以看到,随着每加仑汽油所 行驶里程的增加,车重和发动机排量都逐渐减少。

一般来说,统计人员使用R时都倾向于避免用气泡图,原因和避免使用饼图一样:相比对长 度的判断,人们对体积/面积的判断通常更困难。但是气泡图在商业应用中非常受欢迎,

11.2 折线图

opar <- par(no.readonly=TRUE) 
par(mfrow=c(1,2)) 
t1 <- subset(Orange, Tree==1) 
plot(t1$age, t1$circumference, 
 xlab="Age (days)", 
 ylab="Circumference (mm)", 
 main="Orange Tree 1 Growth") 
plot(t1$age, t1$circumference, 
 xlab="Age (days)", 
 ylab="Circumference (mm)", 
 main="Orange Tree 1 Growth", 
 type="b") 
par(opar) 

折线图一般可用下列两个函数之一来创建:

plot(x, y, type=) 
lines(x, y, type=)

可以看到,type="p"生成了典型的散点图,type="b"是最 常见的折线图。b和c间的不同之处在于点是否出现或者线之间是否有空隙。type="s"和 type="S"都生成阶梯线(阶梯函数),但第一种类型是先横着画线,然后再上升,而第二种类型 则是先上升,再横着画线。

  • plot()和lines()函数工作原理并不相同:
    • plot()函数是在被调用时创建一幅新图,
    • 而lines()函数则是在已存在的图形上添加信息,并不能自己生成图形。
    • 因此,lines()函数通常是在plot()函数生成一幅图形后再被调用。

如果对图形有要求,你可以先通过plot()函数中的type="n"选项来创建坐标轴、标题和其他图形特征,然后再使用 lines()函数添加各种需要绘制的曲线。

  • 我们以绘制五种橘树随时间推移的生长状况为例,逐步展示一个更复杂折线图的创建过程。 每种树都有自己独有的线条。
Orange$Tree <- as.numeric(Orange$Tree) 
# 方便起见,将因子型转化为数值型

ntrees <- max(Orange$Tree) 
xrange <- range(Orange$age) 
yrange <- range(Orange$circumference)
plot(xrange, yrange, 
 type="n", 
 xlab="Age (days)", 
 ylab="Circumference (mm)" 
 )  
# plot()先创建空图形,只设定了轴标签和轴范围,并没有绘制任何数据点
colors <- rainbow(ntrees) 
linetype <- c(1:ntrees) 
plotchar <- seq(18, 18+ntrees, 1) 
# 创建图形


for (i in 1:ntrees) { 
 tree <- subset(Orange, Tree==i) 
 lines(tree$age, tree$circumference,
 type="b", 
 lwd=2, 
 lty=linetype[i], 
 col=colors[i], 
 pch=plotchar[i] 
 ) 
} 
# 每种橘树独有的折线和点都是随后通过lines()函数来添加的


title("Tree Growth", "example of line plot") 
legend(xrange[1], yrange[2], 
 1:ntrees, 
 cex=0.8, 
 col=colors, 
 pch=plotchar, 
 lty=linetype, 
 title="Tree"
) 
# 添加图例

11.3 相关图

哪些变量相关性最强?哪些变量相对独立?是否存在某种聚集模式?如果不花点时间和精 力(可能还需要用些彩笔做些注释),单利用这个相关系数矩阵来回答这些问题是比较困难的。 利用corrgram包中的corrgram()函数,你可以用图形的方式展示该相关系数矩阵

library(corrgram) 
corrgram(mtcars, order=TRUE, lower.panel=panel.shade, 
 upper.panel=panel.pie, text.panel=panel.txt, 
 main="Corrgram of mtcars intercorrelations") 

  • 我们先从下三角单元格(在主对角线下方的单元格)开始解释这幅图形。
  • 默认地,蓝色和从 左下指向右上的斜杠表示单元格中的两个变量呈正相关。
  • 反过来,红色和从左上指向右下的斜杠 表示变量呈负相关。
  • 色彩越深,饱和度越高,说明变量相关性越大。相关性接近于0的单元格基 本无色。

  • 本图为了将有相似相关模式的变量聚集在一起,对矩阵的行和列都重新进行了排序(使 用主成分法)。 从图中含阴影的单元格中可以看到,gear、am、drat和mpg相互间呈正相关,wt、disp、 hp和carb相互间也呈正相关。但第一组变量与第二组变量呈负相关。你还可以看到carb和am、 vs和gear、vs和am以及drat和qsec四组变量间的相关性很弱。 上三角单元格用饼图展示了相同的信息。颜色的功能同上,但相关性大小由被填充的饼图块 的大小来展示。正相关性将从12点钟处开始顺时针填充饼图,而负相关性则逆时针方向填充饼图。
corrgram(x, order=, panel=, text.panel=, diag.panel=) 
  • 当order=TRUE时,相关矩阵将使用主成分分析法对变量重 排序,这将使得二元变量的关系模式更为明显。
  • 选 项 panel 设定非对角线面板使用的元素类型。
  • 你可以通过选项 lower.panel 和 upper.panel来分别设置主对角线下方和上方的元素类型。
  • 而text.panel和diag.panel选项 控制着主对角线元素类型。

#例子2
library(corrgram) 
corrgram(mtcars, order=TRUE, lower.panel=panel.ellipse, 
 upper.panel=panel.pts, text.panel=panel.txt, 
 diag.panel=panel.minmax, 
 main="Corrgram of mtcars data using scatter plots 
 and ellipses") 

  • 我们在下三角区域使用平滑拟合曲线和置信椭圆,上三角区域使用散点图;主对角面板包含变量最小和最大值。矩阵 的行和列利用主成分分析法进行了重排序

library(corrgram) 
corrgram(mtcars, lower.panel=panel.shade, 
 upper.panel=NULL, text.panel=panel.txt, 
 main="Car Mileage Data (unsorted)") 

  • 你能自主控制corrgram()函数中使用的颜色。例如,你 可在col.corrgram()函数中用colorRampPallette()函数来指定四种颜色:
library(corrgram) 
cols <- colorRampPalette(c("darkgoldenrod4", "burlywood1", 
 "darkkhaki", "darkgreen")) 
corrgram(mtcars, order=TRUE, col.regions=cols, 
 lower.panel=panel.shade, 
 upper.panel=panel.conf, text.panel=panel.txt, 
 main="A Corrgram (or Horse) of a Different Color") 

11.4 马赛克图:两个以上的类别型变量

但如果变量是类 别型的呢?若只观察单个类别型变量,可以使用柱状图或者饼图;若存在两个类别型变量,可以 使用三维柱状图(不过,这在R中不太容易做到);但若有两个以上的类别型变量,该怎么办呢?

在马赛克图中,嵌套矩形面积正比于单元格频率, 其中该频率即多维列联表中的频率。颜色和/或阴影可表示拟合模型的残差值

  • 更多图形细节可 参考Meyer、Zeileis和Hornick(2006),或者Michael Friendly的优秀教程(http://datavis.ca)。
  • Steve Simon曾编辑过一个非常优秀的绘制马赛克图的概念教程,可在http://www.childrensmercy.org/ stats/definitions/mosaic.htm获取。

vcd包中的mosaic()函数可以绘制马赛克图。(R基础安装中的mosaicplot()也可绘制马 赛克图,但我还是推荐vcd包,因为它具有更多扩展功能。)

  • 以基础安装中的Titanic数据集为 例,它包含存活或者死亡的乘客数、乘客的船舱等级(一等、二等、三等和船员)、性别(男性、 女性),以及年龄层(儿童、成人)。

 

library(vcd) 
mosaic(~Class+Sex+Age+Survived, data=Titanic, shade=TRUE, legend=TRUE) 

马赛克图隐含着大量的数据信息。

例如:

  • (1) 从船员到头等舱,存活率陡然提高;
  • (2) 大部分 孩子都处在三等舱和二等舱中;
  • (3) 在头等舱中的大部分女性都存活了下来,而三等舱中仅有一 半女性存活;
  • (4) 船员中女性很少,导致该组的Survived标签重叠(图底部的No和Yes)

扩展的马赛克图添加了颜色和阴影来表示拟合模型的残差值

  • 蓝色阴影表明,在假定生存率与船舱等级、性别和年龄层无关的条件下,该类别下的生存率通常超过预期值。
  • 红色 阴影则含义相反。一定要运行该例子的代码,这样你才可以真实感受着色图形的效果。图形表明,
  • 在模型的独立条件下,头等舱女性存活数和男性船员死亡数超过模型预期值。
  • 如果存活数与船舱 等级、性别和年龄层独立,
  • 三等舱男性的存活数比模型预期值低。
  • 尝试运行example(mosaic), 可以了解更多马赛克图的细节

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值