ggplot2热图中相同数值显示不同颜色的问题排查
ggplot2热图数值与颜色不匹配问题排查
问题描述
使用ggplot2绘制混淆矩阵热图时,geom_text标注的数值显示正确,但相同数值对应的色块颜色却不一致(比如Urban行的0.04)。数据集及绘图代码如下:
数据集前8行
> head(zoo_cm.df, 8) Prediction Reference Freq 1 Castle/Castrum Castle/Castrum 0.75 2 Religious Castle/Castrum 0.00 3 Rural Castle/Castrum 0.05 4 Rural site, villa Castle/Castrum 0.00 5 Urban Castle/Castrum 0.04 6 Urban, amphitheater Castle/Castrum 0.00 7 Castle/Castrum Religious 0.00 8 Religious Religious 1.00
数据集结构
> dput(zoo_cm.df) structure(list(Prediction = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L), levels = c("Castle/Castrum", "Religious", "Rural", "Rural site, villa", "Urban", "Urban, amphitheater" ), class = "factor"), Reference = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L ), levels = c("Castle/Castrum", "Religious", "Rural", "Rural site, villa", "Urban", "Urban, amphitheater"), class = "factor"), Freq = c(0.75, 0, 0.05, 0, 0.04, 0, 0, 1, 0.05, 0, 0.03, 0, 0.17, 0, 0.74, 0, 0.15, 0, 0, 0, 0.05, 0.33, 0.04, 0, 0.08, 0, 0.11, 0.67, 0.72, 0, 0, 0, 0, 0, 0.01, 1)), row.names = c(NA, -36L), class = "data.frame")
原绘图代码
zoo_test_cm.plot <- ggplot(zoo_cm.df, aes(x=Prediction, y=Reference)) + geom_tile(aes(fill=Freq)) + geom_text(aes(Reference, Prediction, label = Freq), color = "black", size = 4) + scale_fill_gradient(low = "#FFFFFF", high = "#A6D1E6") + theme_minimal()+ theme(axis.text.x = element_text(angle = 45, vjust = 1, size = 10, hjust = 1), legend.position = "right")+ coord_fixed()
问题根源
geom_text的映射参数错误:主图的aes定义了x=Prediction, y=Reference,但geom_text里却把x设为Reference、y设为Prediction,导致文本的位置与对应的色块完全错位。你看到的“相同数值颜色不同”,其实是文本标注到了错误的色块上,并非颜色刻度本身的问题。
比如Urban行的0.04,实际对应的色块是Prediction=Urban, Reference=Castle/Castrum,但文本却被放到了Prediction=Castle/Castrum, Reference=Urban的位置,而那个位置的Freq是0.08,所以颜色自然不一样。
修正后的代码
将geom_text的aes参数与主图保持一致,不需要重复指定x和y(因为会继承主图的映射),或者显式指定正确的x和y:
zoo_test_cm.plot <- ggplot(zoo_cm.df, aes(x=Prediction, y=Reference)) + geom_tile(aes(fill=Freq)) + # 方法1:继承主图的x/y映射,只指定label geom_text(aes(label = Freq), color = "black", size = 4) + # 方法2:显式指定正确的x/y(和主图一致) # geom_text(aes(x=Prediction, y=Reference, label = Freq), color = "black", size = 4) + scale_fill_gradient(low = "#FFFFFF", high = "#A6D1E6") + theme_minimal()+ theme(axis.text.x = element_text(angle = 45, vjust = 1, size = 10, hjust = 1), legend.position = "right")+ coord_fixed()
验证效果
修正后,每个文本标注都会精准对应到所属的色块,数值和颜色刻度将完全匹配,相同数值的色块颜色也会一致。
内容的提问来源于stack exchange,提问作者Roberto
相关产品推荐
相关产品推荐

