R 数据可视化 —— 相关系数图
一、ggplot 相关系数图
前言
相关系数图是对相关系数矩阵进行可视化的,用于展示多组变量之间的相关性。
根据数据的分布特征,可以应用不同的相关系数计算方法,如 pearson
、spearman
、Kendall
等
相关系数矩阵的可视化图形,可以是热图、气泡图、方块图、椭圆图,也可以是纯数字文本形式,等等。
下面我们介绍它们的绘制方法
示例
我们首先使用 ggplot2
包提供的函数来绘制这些图形
先计算相关系数矩阵
mat <- as.data.frame(round(cor(mtcars), 2))
mat$var1 <- rownames(mat)
data <- gather(mat, key = "var2", value = "corr", -var1)
1. 热图
library(RColorBrewer)
# 获取 5 个颜色
my_color <- brewer.pal(5, "Spectral")
ggplot(data, aes(var1, var2, fill = corr)) +
geom_tile(colour = "black") +
scale_fill_gradientn(colours = my_color)

2. 气泡图
ggplot(data, aes(var1, var2, fill = corr)) +
geom_point(aes(size = abs(corr)), shape = 21, colour = "black") +
scale_fill_gradientn(colours = my_color) +
scale_size_area(max_size = 15, guide = FALSE)

3. 方块图
只要设置参数 shape = 22
,就可以换成方块了
geom_point(aes(size = abs(corr)), shape = 22, colour = "black")

4. 设置标签
使用 geom_text
添加标签
geom_text(aes(label = corr), size = 3, colour = "black", alpha = 0.7)


为正负相关设置不同的颜色
geom_point(aes(fill = corr > 0, size = corr), shape = 21)

5. 混合绘图
如果想绘制上三角或下三角该怎么做?
ggplot2
并没有提供相应的操作,但是我们可以手动对数据进行处理,将对应的数据赋值为 NA
比如,我想绘制下三角。首先,把上三角赋值为 NA
mat <- as.data.frame(round(cor(mtcars), 2))
for (i in 1:10) {
for (j in (i+1):11) {
mat[i,j] <- NA
}
}
然后将变量名的顺序固定为行名顺序
mat$var1 <- rownames(mat)
data <- gather(mat, key = "var2", value = "corr", -var1) %>%
mutate(var1 = factor(var1, levels = rownames(mat)),
var2 = factor(var2, levels = rownames(mat)))
然后绘制图形
my_color <- brewer.pal(5, "Spectral")
ggplot(data, aes(var1, var2)) +
geom_point(aes(fill = corr, size = corr), shape = 21) +
geom_text(aes(label = corr), size = 3, colour = "white") +
scale_fill_gradientn(colours = my_color) +
scale_size_area(max_size = 15, guide = FALSE) +
theme(legend.position = "none")

如果想将文本和形状分别绘制在上三角和下三角,操作也是类似的,只是要多添加一个上三角矩阵。
mat1 <- as.data.frame(round(cor(mtcars), 2))
for (i in 1:10) {
for (j in (i+1):11) {
mat1[i,j] <- NA
}
}
mat2 <- as.data.frame(round(cor(mtcars), 2))
for (i in 1:11) {
for (j in 1:i) {
mat2[i,j] <- NA
}
}
mat1$var1 <- rownames(mat1)
data1 <- gather(mat1, key = "var2", value = "corr", -var1) %>%
mutate(var1 = factor(var1, levels = rownames(mat1)),
var2 = factor(var2, levels = rownames(mat1)))
mat2$var1 <- rownames(mat2)
data2 <- gather(mat2, key = "var2", value = "corr", -var1) %>%
mutate(var1 = factor(var1, levels = rownames(mat2)),
var2 = factor(var2, levels = rownames(mat2)))
my_color <- brewer.pal(5, "Spectral")
ggplot(data1, aes(var1, var2)) +
geom_point(aes(fill = corr, size = corr), shape = 21) +
geom_text(data = data2, aes(label = corr, colour = corr), size = 5) +
scale_fill_gradientn(colours = my_color) +
scale_colour_gradientn(colours = my_color) +
scale_size_area(max_size = 15, guide = FALSE) +
theme(legend.position = "none")

如果要将对角线换成变量名,也很简单
mat1 <- as.data.frame(round(cor(mtcars), 2))
for (i in 1:11) {
for (j in i:11) {
mat1[i,j] <- NA
}
}
mat2 <- as.data.frame(round(cor(mtcars), 2))
for (i in 1:11) {
for (j in 1:i) {
mat2[i,j] <- NA
}
}
var_name <- data1 %>%
filter(var1 == var2)
mat1$var1 <- rownames(mat1)
data1 <- gather(mat1, key = "var2", value = "corr", -var1) %>%
mutate(var1 = factor(var1, levels = rownames(mat1)),
var2 = factor(var2, levels = rownames(mat1)))
mat2$var1 <- rownames(mat2)
data2 <- gather(mat2, key = "var2", value = "corr", -var1) %>%
mutate(var1 = factor(var1, levels = rownames(mat2)),
var2 = factor(var2, levels = rownames(mat2)))
my_color <- brewer.pal(5, "Spectral")
ggplot(data1, aes(var1, var2)) +
geom_point(aes(fill = corr, size = corr), shape = 21) +
#geom_point(data = data2, aes(fill = corr, size = corr), shape = 23) +
geom_text(data = data2, aes(label = corr, colour = corr), size = 5) +
geom_text(data = var_name, aes(label = var1), size = 5) +
scale_fill_gradientn(colours = my_color) +
scale_colour_gradientn(colours = my_color) +
scale_size_area(max_size = 15, guide = FALSE) +
scale_x_discrete(position = 't') +
theme(
legend.position = "none",
axis.title = element_blank()
)

方块配圆形
geom_point(data = data2, aes(fill = corr, size = corr), shape = 22) +
# geom_text(data = data2, aes(label = corr, colour = corr), size = 5) +

热图配圆形
ggplot(data1, aes(var1, var2)) +
geom_tile(data = data2, aes(fill = corr), na.rm = TRUE) +
geom_text(data = data2, aes(label = corr), colour = "black", size = 5) +
geom_point(aes(fill = corr, size = corr), shape = 21) +
geom_text(data = var_name, aes(label = var1), size = 5) +
scale_fill_gradientn(colours = my_color, na.value = "white") +
scale_colour_gradientn(colours = my_color) +
scale_size_area(max_size = 15, guide = FALSE) +
scale_x_discrete(position = 't') +
theme(
panel.background = element_blank(),
legend.position = "none",
axis.title = element_blank()
)

注意,需要将 geom_tile
放在最前面,同时设置 na.value
参数的值
代码:https://github.com/dxsbiocc/learn/blob/main/R/plot/corr_plot.R
总结一下,其实用 ggplot2
做个性化绘图没那么难,重要的是理解其中的原理。
二、corrplot 相关系数图
前言
前面,我们介绍了如何使用 ggplot2
来绘制相关系数图,这节,我们将介绍用 corrplot
包绘制相关系数图
corrplot
主要用于图形化展示相关系数矩阵、置信区间,同时还包含一些矩阵排序算法。同时能够以简单的方式,选择颜色、文本标签和布局等
安装导入
if (!require(corrplot)) {
install.packages("corrplot")
}
library(corrplot)
可视化方法
corrplot
包含 7
种可视化方法,可使用 method
参数来进行选择,参数值如下
-
circle
:圆形
mat <- cor(mtcars)
corrplot(mat, method = "circle")

-
square
:方形
corrplot(mat, method = "square")

-
ellipse
:椭圆
corrplot(mat, method = "ellipse")

-
number
:数值
corrplot(mat, method = "number")

-
shade
:阴影
corrplot(mat, method = "shade")

-
color
:热图
corrplot(mat, method = "color")

-
pie
:饼图
corrplot(mat, method = "pie")

默认情况下,使用红蓝两种颜色,正相关显示为蓝色,负相关为红色,颜色的强度和图形的大小与相关性成正比
布局方式
corrplot
有三种布局方式,通过 type
参数设置
-
full
: 默认值,绘制整个相关系数矩阵 -
upper
: 绘制上三角矩阵 -
lower
: 绘制下三角矩阵
例如,上三角
corrplot(mat, method = "circle", type = "upper")

下三角
corrplot(mat, method = "circle", type = "lower")

那如何将不同图形混合绘制呢?
corrplot
提供了一个封装函数 corrplot.mixed
,用于绘制混合图形
该函数通过 lower
, upper
两个参数指定上下三角的类型,例如
corrplot.mixed(mat)

默认绘制上三角为圆形下三角为数字的图形
设置对角线标签放置的位置 tl.pos
和对角线图像类型 diag
tl.pos
可以是 lt
、d
、n
,分别表示放在左侧、对角线或不显示
diag
可以是 u
、l
、n
分别表示与上、下三角一致或不绘制
corrplot.mixed(mat, tl.pos = "lt", diag = 'l')

设置颜色,其中 tl.col
为对角线标签颜色,lower.col
和 upper.col
分别表示上、下三角的颜色
library(RColorBrewer)
corrplot.mixed(mat, lower = "ellipse", upper = "circle", tl.col = "black",
lower.col = brewer.pal(5, "Spectral"),
upper.col = brewer.pal(5, "Set2"))

矩阵重排
我们可以根据相关系数对矩阵进行重排,从矩阵中找到隐藏的结构和模式。
corrplot
有 4
种排序方法,通过 order
参数设置:
-
AOE
:特征向量的角度顺序 -
FPC
:第一主成分顺序 -
hclust
:层次聚类的顺序,可以使用hclust.method
参数设置距离度量方法 -
alphabet
:字母表顺序
corrplot(mat, order = "AOE")

corrplot(mat, order = "hclust")

对于 hclust
方式,可以为聚类结果绘制矩形,使用 addrect
参数来指定需要绘制矩形的数量
corrplot(mat, order = "hclust", hclust.method = "median", addrect = 3)

根据聚类结果,将颜色设置为 3
种,同时更改背景色
corrplot(mat, order = "hclust", hclust.method = "median", addrect = 3,
col = brewer.pal(3, "Set1"), bg = brewer.pal(7, "Set2")[7])

设置文本标签及图例
cl.*
参数是设置颜色图例的参数,tl.*
是设置文本图例的参数
例如,tl.col
和 tl.srt
用来设置文本标签的颜色和旋转
corrplot(mat, order = "FPC", cl.pos = "b", tl.srt = 45)

corrplot(mat, order = "FPC", cl.ratio = 0.2, cl.align = "l")

corrplot(mat, order = "hclust", type = "lower",
tl.pos = 'd', tl.cex = 1.25, tl.srt = 45, tl.col = "black")

缺失值处理
默认情况下,corrplot
会将 NA
值渲染为 ?
可以使用 na.label
参数设置 NA
值的显示
mat2 <- mat
diag(mat2) <- NA
corrplot(mat2)

corrplot(mat2, na.label = "*")

plotmath 表达式
可以在文本标签前面加上 :
、=
、$
字符前缀,来激活 plotmath
表达式渲染
mat2 <- mat[1:5,1:5]
colnames(mat2) <- c("alpha", "beta", ":alpha+beta", ":a[0]", "=a[beta]")
rownames(mat2) <- c("alpha", "beta", NA, "$a[0]", "$ a[beta]")
corrplot(mat2)

添加显著性检验
我们还可以在图像中添加显著性信息。首先,使用 cor.mtest
计算显著性 p
值和置信区间
> pmat <- cor.mtest(mtcars, conf.level = .95)
> str(pmat)
List of 3
$ p : num [1:11, 1:11] 0.00 6.11e-10 9.38e-10 1.79e-07 1.78e-05 ...
$ lowCI: num [1:11, 1:11] 1 -0.926 -0.923 -0.885 0.436 ...
$ uppCI: num [1:11, 1:11] 1 -0.716 -0.708 -0.586 0.832 ...
然后将计算结果中的 p
值传递给 p.mat
参数,同时设置显著性水平 sig.level
,高于该值的相关系数被认为是不显著的
corrplot(mat, p.mat = pmat$p, sig.level = 0.05)

可以看到,不显著的相关系数被画 Ⅹ
了,我们可以设置 insig = "blank"
不显示不显著的点
corrplot(mat, p.mat = pmat$p, sig.level = 0.05,
insig = "blank")

insig
参数还支持其他值
-
pch
: 默认值 -
p-value
: 显示 p 值
-
n
: 不做任何操作 -
label_sig
: 用 * 来表示显著性
搭配 sig.level
使用,按照等级绘制多个 *
corrplot(mat, p.mat = pmat$p, sig.level = c(.001, .01, .05),
insig = "label_sig", pch.cex = 0.9, pch.col = "white")

pch
参数可以设置显著的点的显示文本
corrplot(mat, p.mat = pmat$p, sig.level = 0.05, pch = "p < 0.05",
insig = "label_sig", pch.cex = 0.7, pch.col = "white")

显示置信区间
根据上一步计算出的置信上下限,我们可以展示变量之间的置信区间
使用 lowCI.mat
和 uppCI.mat
来设置置信区间的上下限,使用 plotCI
参数来设置显示的图形,支持 n
(不显示), square
, circle
, rect
四种类型
corrplot(mat, lowCI.mat = pmat$lowCI, uppCI.mat = pmat$uppCI,
order = "hclust", plotCI = "rect", cl.pos = "n")

最后,需要说明的一点是,该包不只是针对相关系数矩阵,也可以绘制其他类型的矩阵
例如
ran <- round(matrix(runif(225, -100,100), 15))
corrplot(ran, is.corr = FALSE, method = "ellipse", cl.lim = c(-100, 100))

如果行列数不一致,可以使用 win.asp
参数将图形调整为正方形
ran <- matrix(rnorm(70), ncol = 7)
corrplot(ran, is.corr = FALSE, win.asp = .7, method = "circle")
