9 中级绘图
在“基本图形”中所接触的图形,主要用于展示单类别型或连续型变量的分布情况,此处将介绍更多用于展示双变量间关系(二元关系)和多变量间关系(多元关系)的绘图方法。
9.1 散点图
散点图可用来描述两个连续型变量间的关系,让我们从最简单的plot()函数出发。
1
2
3
4
|
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
)
|
生成的图形中包括散点图、一条最佳拟合直线(abline)和一条平滑曲线(lowess)。
现在使用car包中的scatterplot()函数绘制一个增强的版本,绘制不同气缸数量汽车每加仑英里数对车重的图形,包括散点图、拟合直线和平滑曲线。
1
2
|
library
(
car
)
scatterplot
(
mpg
~
wt
|
cyl
,
data
=
mtcars
,
lwd
=
2
,
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"
)
|
散点图矩阵
散点图矩阵用于展示多幅散点图,pairs()函数可以创建基础的散点图矩阵,以下代码包含mpg、disp、drat和wt中任意两者的散点图。
1
|
pairs
(
~
mpg
+
disp
+
drat
+
wt
,
data
=
mtcars
,
main
=
"Basic Scatter Plot Matrix"
)
|
car包的scatterplotMatrix()函数也可以生成散点图矩阵,并支持以下操作:
- 以某个因子为条件绘制散点图矩阵;
- 包含线型和平滑拟合曲线;
- 在主对角线放置箱线图、密度图或者直方图;
- 在各单元格的边界添加轴须图。
1
2
|
library
(
car
)
scatterplotMatrix
(
~
mpg
+
disp
+
drat
+
wt
,
data
=
mtcars
,
spread
=
FALSE
,
lty
.
smooth
=
2
,
main
=
"Scatter Plot Matrix via car Package"
)
|
spread=FALSE选项表示不添加展示分散度和对称信息的直线。
再来一个scatterplotMatrix()函数的使用例子,主对角线的核密度曲线改为了直方图,并且直方图以汽车气缸数为条件绘制。
1
2
|
library
(
car
)
scatterplotMatrix
(
~
mpg
+
disp
+
drat
+
wt
|
cyl
,
data
=
mtcars
,
spread
=
FALSE
,
diagonal
=
"histogram"
,
main
=
"Scatter Plot Matrix via car Package"
)
|
gclus包中的cpairs()函数提供了一个有趣的散点图矩阵变种,支持重排矩阵中变量的位置,让相关性更高的变量更靠近主对角线,还可以对各单元格进行颜色编码来展示变量间的相关性大小。
首先查看各个变量之间相关性的大小:
1
|
cor
(
mtcars
[
c
(
"mpg"
,
"wt"
,
"disp"
,
"drat"
)
]
)
|
可以发现相关性最高(0.89)的是车重(wt)和排量(disp),以及车重(wt)和每加仑英里数(mpg)。相关性最低(0.68)的是每加仑英里数(mpg)和后轴比(drat)。以下代码根据相关性大小,对散点图矩阵中的这些变量重新排序并着色。
1
2
3
4
5
6
|
library
(
gclus
)
mydata
<
-
mtcars
[
c
(
1
,
3
,
5
,
6
)
]
mydata
.
corr
<
-
abs
(
cor
(
mydata
)
)
mycolors
<
-
dmat
.
color
(
mydata
.
corr
)
myorder
<
-
order
.
single
(
mydata
.
corr
)
cpairs
(
mydata
,
myorder
,
panel
.
colors
=
mycolors
,
gap
=
.
5
,
main
=
"Variables Ordered and Colored by Correlation"
)
|
高密度散点图
当散点图中点数量过大时,数据点的重叠将会导致绘图效果显著变差。对于这种情况,可以使用封箱、颜色和透明度等来指定图中任意点上重叠点的数目。
smoothScatter()函数可利用核密度估计生成用颜色密度来表示点分布的散点图。
1
2
3
4
5
6
7
8
|
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"
)
smoothScatter
(
mydata
$
x
,
mydata
$
y
,
main
=
"Scatterplot Colored by Smoothed Densities"
)
|
hexbin包中的hexbin()函数将二元变量的封箱放到六边形单元格中。
1
2
3
|
library
(
hexbin
)
bin
<
-
hexbin
(
mydata
$
x
,
mydata
$
y
,
xbins
=
50
)
plot
(
bin
,
main
=
"Hexagonal Binning with 10000 Observations"
)
|
IDPmisc包中的iplot()函数也可以通过颜色来展示点的密度。
1
2
|
library
(
IDPmisc
)
iplot
(
mydata
$
x
,
mydata
$
y
,
main
=
"Image Scatter Plot with Color Indicating Density"
)
|
三维散点图
如果想一次性对三个定量变量的交互进行可视化,那么可以使用scatterplot3d中的scatterplot3d()函数进行绘制。
1
2
3
4
|
library
(
scatterplot3d
)
attach
(
mtcars
)
scatterplot3d
(
wt
,
disp
,
mpg
,
main
=
"Basic 3D Scatter Plot"
)
detach
(
mtcars
)
|
scatterplot3d()函数提供了许多选项,包括设置图形符号、轴、颜色、线条、网格线、突出显示和角度等功能。例如以下代码生成一幅突出显示效果的三维散点图,增强了纵深感并添加了连接点与水平面的垂直线。
1
2
3
4
|
library
(
scatterplot3d
)
attach
(
mtcars
)
scatterplot3d
(
wt
,
disp
,
mpg
,
pch
=
16
,
highlight
.
3d
=
TRUE
,
type
=
"h"
,
main
=
"3D Scatter Plot with Vertical Lines"
)
detach
(
mtcars
)
|
还可以再加上一个回归面。
1
2
3
4
5
6
|
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
)
detach
(
mtcars
)
|
使用rgl包中的plot3d()函数可创建交互式的三维散点图,通过鼠标即可对图形进行旋转。
1
2
3
4
|
library
(
rgl
)
attach
(
mtcars
)
plot3d
(
wt
,
disp
,
mpg
,
col
=
"red"
,
size
=
5
)
detach
(
mtcars
)
|
Rcmdr包中的scatter3d()函数可以实现类似功能。
1
2
3
4
|
library
(
Rcmdr
)
attach
(
mtcars
)
scatter3d
(
wt
,
disp
,
mpg
)
detach
(
mtcars
)
|
气泡图
三维散点图用z轴表示第三个变量的大小,另一种思路是:先创建一个二维散点图,然后用点的大小来代表第三个变量的值,即气泡图。
使用symbols()函数来创建气泡图,支持的形状包括圆圈图、方形图、星形图、温度计图和箱线图,以绘制圆圈图为例:
1
|
symbols
(
x
,
y
,
circle
=
radius
)
|
如果想用面积而不是半径来表示第三个变量,则需要进行转换:
1
|
symbols
(
x
,
y
,
circle
=
sqrt
(
z
/
pi
)
)
|
以下代码中,x轴表示车重,y轴表示每加仑英里数,气泡大小表示发动机排量。
1
2
3
4
5
|
attach
(
mtcars
)
r
<
-
sqrt
(
disp
/
pi
)
symbols
(
wt
,
mpg
,
circle
=
r
,
inches
=
.
30
,
fg
=
"white"
,
bg
=
"lightblue"
,
main
=
"Bubble Plot with Point Size Proportional to Displacement"
,
ylab
=
"Miles Per Gallon"
,
xlab
=
"Weight of Car"
)
text
(
wt
,
mpg
,
rownames
(
mtcars
)
,
cex
=
.
5
)
detach
(
mtcars
)
|
一般来说,统计人员使用R时都倾向于避免使用气泡图,原因和避免使用饼图一样:相对于长度的判断,人们对体积/面积的判断通常更加困难。
9.2 折线图
将散点图上的点从左往右连接起来,即可得到折线图。以基础安装中的Orange数据集为例,绘制第一种树数据的散点图和折线图。
1
2
3
4
5
6
|
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
)
|
两幅图的区别取决于参数type=”b”,折线图一般可用以下两个函数之一来创建:
1
2
|
plot
(
x
,
y
,
type
=
)
lines
(
x
,
y
,
type
=
)
|
type=可选值如下:
- p:只有点;
- l:只有线;
- o:实心点和线(即线覆盖在点上);
- b、c:线连接点(c时不绘制点);
- s、S:阶梯线;
- h:直方图式的垂直线;
- n:不生成任何点和线(通常用来为后面的命令创建坐标轴)
以下展示一个更复杂的折线图创建过程,每种树都有自己独有的线条。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Orange
$
Tree
<
-
as
.
numeric
(
Orange
$
Tree
)
ntrees
<
-
max
(
Orange
$
Tree
)
xrange
<
-
range
(
Orange
$
age
)
yrange
<
-
range
(
|