geom_raster绘制热图列顺序异常,该如何解决?
双三角矩阵热图列顺序异常问题解决
问题场景
使用10×10双三角矩阵表示变量间的两种相关性,以4×4数据集为例,通过ggplot2的geom_raster绘制热图:为上下三角区域设置不同颜色刻度,对角线(自相关,值为NA)设为灰色。但生成的热图列顺序异常,预期的第一列内容跑到了最后一列,调整因子水平后问题仍未解决。
示例数据集
ff <- data.frame(Var1=as.factor(c("V1", "V2", "V3","V4", "V1", "V2", "V3","V4", "V1", "V2", "V3","V4", "V1", "V2","V3","V4")), Var2=as.factor(c("V1", "V1", "V1", "V1", "V2", "V2", "V2", "V2", "V3", "V3","V3","V3", "V4", "V4", "V4","V4")), value=c(NA, 0.1, 0.2, 0.2, 0.4, NA, 0.3, 0.4, 0.5, 0.5, NA, 0.3, 0.2, 0.3, 0.3, NA))
原绘图代码
ggplot(ff, aes(Var1, Var2)) + # The first layer, with its own fill scale geom_raster( data = ~ subset(.x, as.numeric(Var1) > as.numeric(Var2)), aes(fill = value) ) + scale_fill_distiller(palette = "Blues") + # Declare new fill scale for the second layer new_scale_fill() + geom_raster( data = ~ subset(.x, as.numeric(Var1) < as.numeric(Var2)), aes(fill = value) ) + scale_fill_distiller(palette = "Reds", direction=-1) + # I'm not sure what to do with the diagonal. Make it grey? new_scale_fill() + geom_raster( data = ~ subset(.x, as.numeric(Var1) == as.numeric(Var2)), aes(fill = value) ) + scale_fill_distiller(palette = "Greys", guide = "none")
问题原因
- ggplot默认按因子水平顺序排列坐标轴,但y轴(Var2)是从下到上显示水平,与热图常规的从上到下排列(V1在最上方)不符,导致视觉上列顺序颠倒
- 对角线处理使用额外的颜色刻度,冗余且可能干扰坐标轴布局
解决方案
修正后完整代码
# 显式设置因子水平,确保顺序为V1-V4 ff$Var1 <- factor(ff$Var1, levels = c("V1", "V2", "V3", "V4")) ff$Var2 <- factor(ff$Var2, levels = c("V1", "V2", "V3", "V4")) library(ggplot2) library(ggnewscale) # 必须加载该包才能使用new_scale_fill ggplot(ff, aes(Var1, Var2)) + # 下三角区域(Var1 > Var2):蓝色刻度 geom_raster(data = ~ subset(.x, as.numeric(Var1) > as.numeric(Var2)), aes(fill = value)) + scale_fill_distiller(palette = "Blues", name = "下三角相关性") + # 启用新的填充刻度 new_scale_fill() + # 上三角区域(Var1 < Var2):红色刻度 geom_raster(data = ~ subset(.x, as.numeric(Var1) < as.numeric(Var2)), aes(fill = value)) + scale_fill_distiller(palette = "Reds", direction = -1, name = "上三角相关性") + # 对角线区域:直接设置固定灰色填充,无需额外刻度 geom_raster(data = ~ subset(.x, as.numeric(Var1) == as.numeric(Var2)), fill = "grey80") + # 反转y轴,让V1显示在热图最上方,匹配常规布局 scale_y_discrete(limits = rev(levels(ff$Var2))) + # 优化标签与主题 labs(x = "变量", y = "变量") + theme_minimal()
关键调整点
- 显式设置因子水平:确保变量顺序固定为V1到Vn,避免默认排序干扰
- 反转y轴方向:通过
scale_y_discrete(limits = rev(levels(ff$Var2)))让y轴从上到下显示V1到V4,匹配热图的常规阅读习惯 - 简化对角线处理:直接为对角线区域设置固定灰色填充,无需使用额外的颜色刻度函数,减少冗余代码
内容的提问来源于stack exchange,提问作者Buczinski
相关产品推荐
相关产品推荐

