相关矩阵的可视化及其新方法探究
你是不鸣则已,一鸣惊人啊。你这两篇文章我都非常喜欢,哈哈
话说《统计研究》上极少发表关于图形的文章,某年我们学院某教授发了一篇闪电图,让我极其无语,其实就是把折线图旋转90°……你的文章比那种论文强多了。
关于圆圈图,我想对角线上的大黑点最好去掉,以免喧宾夺主、影响视觉感受,或者效仿plotcorr()函数给出diag = TRUE/FALSE参数。另外我不知道你的png图形是怎么生成的,感觉不太清晰,所以建议用png()设备指定宽高生成,例:
library(ellipse) # 原文此处有笔误 fit = lm(mpg ~ ., mtcars) png("corr-ellipse2.png", width = 480, height = 480) # 用mar设置作图区域边界为0 plotcorr(summary(fit, correlation = TRUE)$correlation, mar = rep(0, 4)) dev.off()
圆圈图中的代码也有可改进之处,如:
bg=switch(as.integer(c>0)+1,'white','black')
我觉得不如直接用:
bg = c('white', 'black')[c <= 0]
而整个函数也可以矩阵式操作,避免循环(作[latex]n2[/latex]个symbols图可能会很慢):
bg = cor bg[cor > 0] = 'black' bg[cor <= 0] = 'white' # 以下1个symbols()调用完成全图 # ...
[未知用户] 多谢夸奖:)我觉得主对角线上的大黑点还是要保留(或者用黑点表示负系数?),虽然它们都是1,但画出来可以方便别的图形进行比较,这些大黑点算是尺子,正方形的边长也是。png图直接保存的,的确不太清晰,图三中的大黑圆右下角有些瑕疵。
代码先放着,慢慢改进,谢谢指正。不知哪个相关的R包能收录一下:)
谢兄漏打了的画全图的代码是不是这个:
代码先放着,慢慢改进,谢谢指正。不知哪个相关的R包能收录一下:)
谢兄漏打了的画全图的代码是不是这个:
symbols(rep(1:n, each = n), rep(1:n, n), add = TRUE,
circles = as.vector(sqrt(abs(cor))/2), bg = as.vector(bg), inches = F)
[未知用户] 可以看看这个例子,将相关矩阵重新排了序再画图:
library(ellipse) corr.mtcars <- cor(mtcars) ord <- order(corr.mtcars[1,]) xc <- corr.mtcars[ord, ord] colors <- c("#A50F15","#DE2D26","#FB6A4A","#FCAE91","#FEE5D9","white", "#EFF3FF","#BDD7E7","#6BAED6","#3182BD","#08519C") plotcorr(xc, col=colors[5*xc + 6])
圆圈图创得好。
代码改进了一下:
circle.cor = function(cor, axes = FALSE, xlab = "",
ylab = "", asp = 1, title = "Taiyun's cor-matrix circles",
...) {
n = nrow(cor)
par(mar = c(0, 0, 2, 0), bg = "white")
plot(c(0, n + 0.8), c(0, n + 0.8), axes = axes, xlab = "",
ylab = "", asp = 1, type = "n")
##add grid
segments(rep(0.5, n + 1), 0.5 + 0:n, rep(n + 0.5, n + 1),
0.5 + 0:n, col = "gray")
segments(0.5 + 0:n, rep(0.5, n + 1), 0.5 + 0:n, rep(n + 0.5,
n), col = "gray")
##define circles' background color.
##black for positive correlation and white for negative
bg = cor
bg[cor > 0] = "black"
bg[cor <= 0] = "white"
##plot n*n circles using vector language, suggested by Yihui Xie
##the area of circles denotes the absolute value of coefficient
symbols(rep(1:n, each = n), rep(n:1, n), add = TRUE, inches = F,
circles = as.vector(sqrt(abs(cor))/2), bg = as.vector(bg))
text(rep(0, n), 1:n, n:1, col = "red")
text(1:n, rep(n + 1), 1:n, col = "red")
title(title)
}
## an example
data(mtcars)
fit = lm(mpg ~ ., mtcars)
cor = summary(fit, correlation = TRUE)$correlation
circle.cor(cor)
请问如果不是矩阵,而只是根据一个参数画了若干椭圆,例如根据数据中所有变量的四种不同的属性,画了四个椭圆,如何能让他们颜色不同?而且是实心的?
用col = "color"只能改变所有椭圆线条的颜色。
急切盼望不吝赐教
我用的是Vegan包里的ordiellipse函数
用col = "color"只能改变所有椭圆线条的颜色。
急切盼望不吝赐教
我用的是Vegan包里的ordiellipse函数
刚发现永久链接correlation-matrix-isualization最后一个单词漏了一个v。另外恭喜你认识了Romain Francois!
[未知用户] 仔细看看帮助呗,如果col只是边线颜色,那么看看有没有fill之类的参数用来填充颜色。
[未知用户] 这个代码应该就快多了吧?
关于写代码,我有个建议,你好像不太在乎变量名的命名,例如cor、c这样的变量名最好避免使用,因为它们本身就是R的函数。虽然在R里面随意命名一般来说不会有大的问题,但是不排除有时候当你把T/F弄成变量名的时候,a == T/F就不再是a == TRUE/FALSE的意思了。这种bug也不太容易找出来。
关于写代码,我有个建议,你好像不太在乎变量名的命名,例如cor、c这样的变量名最好避免使用,因为它们本身就是R的函数。虽然在R里面随意命名一般来说不会有大的问题,但是不排除有时候当你把T/F弄成变量名的时候,a == T/F就不再是a == TRUE/FALSE的意思了。这种bug也不太容易找出来。
[未知用户] 为啥代码中会有中文引号呢……
library(ellipse) corr.mtcars = cor(mtcars) ord = order(corr.mtcars[1, ]) xc = corr.mtcars[ord, ord] colors = c("#A50F15", "#DE2D26", "#FB6A4A", "#FCAE91", "#FEE5D9", "white", "#EFF3FF", "#BDD7E7", "#6BAED6", "#3182BD", "#08519C") plotcorr(xc, col = colors[5 * xc + 6])
[未知用户] 麻烦之处就在于对距离矩阵的排序,因为它不是一个向量,排序的时候行列都要考虑,如何排才能把相似的元素排到一起?我觉得不妨参考hclust()函数的结果,它的最底层的排序其实正是你这个帖子想要的排序,把hclust()的结果与本文的圆圈图结合起来使用,应该就能达到你要的效果了,不过本文的圆圈图考虑的是相关系数的正负,而距离矩阵只有大小,没有正负,因此黑白颜色的选择可以去掉,只是用圆圈表示距离的大小即可。
在Romain François的建议下,又进一步完善了一下。已经放在R graph gallery上面了。欢迎大家评价。
很好!我建议你再考虑一下颜色参数,使得你的这种图形能够被扩展到可以展示任意矩阵(如聚类的距离矩阵)。用户可以自定义颜色时,相关系数矩阵则可以用
ifelse(corr > 0, "black", "white")
把颜色参数传递进去——它只是矩阵的特例而已。很喜欢这个创意,大概会很快在工作用运用!
太云的创意很好,但我个人认为还可以进一步改进
正如太云指出的,原来的彩色圈图存在色彩杂乱,把最引起关注的大圆给了相关性最小的格子。因此采用有大小的黑白圈图。
但我想原来的彩色圈图至少有1个优点:保留了相关性是反映“X、Y向直线集中的趋势”这个概念
而黑白圈图至少有1个缺点:用实心还是空心表达正负往往让人容易忽视空心圈。
因此我建议不采用黑白圈图而是采用“斜线图”,即格子中的图形采用\和/,大小用斜线的粗细来表达。
这样有以下好处:
1、强调了相关性是反映“X、Y向直线集中的趋势”这个特点。
2、用正斜和反斜表达正负相关
3、保留了原来黑白圈图把最显眼的图形留给相关性最大的格子的特点。
我不会用R,因此无法给出图例,希望我的描述足够清楚。
正如太云指出的,原来的彩色圈图存在色彩杂乱,把最引起关注的大圆给了相关性最小的格子。因此采用有大小的黑白圈图。
但我想原来的彩色圈图至少有1个优点:保留了相关性是反映“X、Y向直线集中的趋势”这个概念
而黑白圈图至少有1个缺点:用实心还是空心表达正负往往让人容易忽视空心圈。
因此我建议不采用黑白圈图而是采用“斜线图”,即格子中的图形采用\和/,大小用斜线的粗细来表达。
这样有以下好处:
1、强调了相关性是反映“X、Y向直线集中的趋势”这个特点。
2、用正斜和反斜表达正负相关
3、保留了原来黑白圈图把最显眼的图形留给相关性最大的格子的特点。
我不会用R,因此无法给出图例,希望我的描述足够清楚。
[未知用户]
但我想原来的彩色圈图至少有1个优点:保留了相关性是反映“X、Y向直线集中的趋势”这个概念。说得太好了,我之前还没有这样想过。
而黑白圈图至少有1个缺点:用实心还是空心表达正负往往让人容易忽视空心圈。这个我倒不很觉得,可能是主对角线上的一排大黑圆影响的吧,要是不喜欢黑白,别的颜色也可以选择。但是,我觉得还是黑白色最为妥当。
格子中的图形采用\和/,大小用斜线的粗细来表达。很新颖的方法,不过我觉得粗细对视觉影响肯定没有面积明显。
As Hills (1969) said, "The first and sometimes only impression gained from looking at a large correlation matrix is its largeness."多谢你的建议,你的描述非常清楚了。
1、只要交待清楚数据来自于(Pearson)相关系数矩阵,那么“线性”就不用再强调了,圆圈越大说明越有直线趋势。
2、至于正负,/和\恐怕在图中就不那么清晰了,看着一团短线。
3、黑白的感受可能取决于个人,我看这幅图觉得简洁,黑的地方表示正相关,剩下“空”的地方表示负相关,还是挺清楚的,如果样本能适当排序,那么前面 linkinbird 说的那个主意就能很好和圆圈图结合使用了,展示聚类现象肯定效果很好。
不过我上面说的都是针对数据量比较大的情况,在少数几个变量之间,用scatterplot matrix就很好展示了,关于这一点,太云兄弟可能会在他下一篇作品中展现。
2、至于正负,/和\恐怕在图中就不那么清晰了,看着一团短线。
3、黑白的感受可能取决于个人,我看这幅图觉得简洁,黑的地方表示正相关,剩下“空”的地方表示负相关,还是挺清楚的,如果样本能适当排序,那么前面 linkinbird 说的那个主意就能很好和圆圈图结合使用了,展示聚类现象肯定效果很好。
不过我上面说的都是针对数据量比较大的情况,在少数几个变量之间,用scatterplot matrix就很好展示了,关于这一点,太云兄弟可能会在他下一篇作品中展现。