如何在geom_tile中用图案/符号替代颜色标记NA值?
解决方案:黑白热力图NA值区分与灰度色阶调整
先模拟贴合你场景的数据:
library(ggplot2) library(ggpattern) # 构造示例数据 df <- data.frame( Source = rep(c("GER", "ESP"), each = 5), Target = rep(c("DE", "ES", "FR", "IT", "UK"), 2), Share = c(NA, 0.12, 0.08, 0.05, 0.03, 0.15, NA, 0.09, 0.06, 0.04) )
1. 用ggpattern给NA单元格添加区分图案
通过geom_tile_pattern为NA值单元格设置专属图案(比如斜线),和灰度填充形成明确区分:
ggplot(df, aes(x = Target, y = Source)) + geom_tile_pattern( aes(fill = Share, pattern = is.na(Share), pattern_density = ifelse(is.na(Share), 0.3, 0)), color = "black" ) + # 灰度填充色阶,NA值保留白色 scale_fill_distiller(palette = "Greys", direction = 1, na.value = "white") + # 指定NA对应的图案类型,非NA无图案 scale_pattern_manual(values = c("none", "stripe")) + labs(x = "目标国家", y = "来源国家", fill = "引用占比") + theme_bw()
关键点:pattern = is.na(Share)触发图案逻辑,pattern_density控制图案密度;除了stripe,还可选crosshatch(交叉线)、dot(圆点)等图案类型。
2. 给NA单元格添加文本/形状
如果不想用图案,可直接在NA位置添加文本或标记形状:
ggplot(df, aes(x = Target, y = Source)) + geom_tile(aes(fill = Share), color = "black") + # 在NA单元格添加"Self"文本 geom_text(data = subset(df, is.na(Share)), label = "Self", color = "black", size = 4) + # 可选:替换成空心圆标记 # geom_point(data = subset(df, is.na(Share)), size = 8, shape = 21, fill = "white") + scale_fill_distiller(palette = "Greys", direction = 1, na.value = "white") + labs(x = "目标国家", y = "来源国家", fill = "引用占比") + theme_bw()
关键点:用subset(df, is.na(Share))精准定位NA单元格,文本/形状的样式可按需调整大小、颜色。
3. 限制灰度色阶,与白色清晰区分
默认灰度色阶可能和白色接近,可通过压缩填充色范围,让有效数据的灰度和NA的白色拉开差距:
# 先提取非NA数据的占比范围 non_na_range <- range(df$Share, na.rm = TRUE) ggplot(df, aes(x = Target, y = Source)) + geom_tile(aes(fill = Share), color = "black") + scale_fill_distiller( palette = "Greys", direction = 1, na.value = "white", # 限制填充色仅覆盖有效数据区间,避免浅灰接近白色 limits = non_na_range, # 可选:手动设置色阶断点,强化区分度 breaks = seq(non_na_range[1], non_na_range[2], length.out = 4) ) + labs(x = "目标国家", y = "来源国家", fill = "引用占比") + theme_bw()
关键点:limits = non_na_range让填充色只覆盖有效数据的灰度区间;direction = 1设置高占比对应深灰,低占比对应浅灰(反向设为-1即可)。
你也可以将图案+色阶调整结合使用,进一步提升黑白出版的可读性。
内容的提问来源于stack exchange,提问作者user18803194
相关产品推荐
相关产品推荐

