在ggplot中调整叠加栅格alpha值时NA区域透明失效问题
问题:ggplot添加alpha后NA区域失去透明度
问题场景
用ggplot绘制数字高程模型(DEM),想叠加带颜色的半透明高亮区域。不加alpha参数时,第二层(geom_raster或geom_tile)的NA区域能正常透明,不遮盖下方DEM;但给第二层加上alpha=0.5后,原本透明的NA区域突然失去透明度,把下面的DEM盖住了。需求很明确:让圆圈内的高亮区域半透明(alpha≈0.5),圆圈外的区域完全透明。
原因
全局设置的alpha会作用于整个图层的所有元素——哪怕你给NA值设置了na.value="transparent",alpha会把这个透明色也叠加半透明效果,导致原本完全透明的区域变成了半透明的背景色(比如白色),自然就遮盖了下方的DEM。na.rm=TRUE只是移除NA对应的图例,并不会真正不绘制这些元素,它们还是会被画出来,只是填充色是透明,加上alpha后就出问题了。
解决方案
方法1:给非NA区域单独设置alpha
把alpha映射到数据,只让需要高亮的非NA区域有alpha值,NA区域的alpha设为0:
geom_tile(aes(x = x, y = y, fill = territory.z, alpha = ifelse(is.na(territory.z), 0, 0.5)), na.rm = T) + guides(alpha = "none") # 不需要显示alpha的图例
方法2:过滤数据,只绘制高亮区域
直接在geom_tile里只传入非NA的行,这样图层只画需要高亮的部分,再设置全局alpha:
geom_tile(data = subset(territory.ex, !is.na(territory.z)), aes(x = x, y = y, fill = territory.z), alpha = 0.5)
完整修正代码(方法2示例)
# 创建模拟DEM数据 DEM.ex <- matrix(0, 100, 100) DEM.ex[c(1:length(DEM.ex))] <- sin(c(1:length(DEM.ex))*0.5) DEM.ex <- DEM.ex*t(DEM.ex)+1 # 创建高亮区域数据 territory.ex <- expand.grid(1:100, 1:100) names(territory.ex)[1:2] <- c("x", "y") territory.ex$territory.z <- ifelse(sqrt((territory.ex$x-40)^2 + (territory.ex$y-40)^2) <= 30, 1, NA) territory.ex$DEM.z <- DEM.ex[1:length(DEM.ex)] # 绘制修正后的图 fixed_plot <- ggplot(territory.ex) + geom_raster(aes(x = x, y = y, fill = DEM.z), na.rm = TRUE) + # 只绘制非NA的高亮区域 geom_tile(data = subset(territory.ex, !is.na(territory.z)), aes(x = x, y = y, fill = territory.z), alpha = 0.5) + scale_fill_gradient(low = "black", high = "white", na.value = "transparent") + theme_light() + guides(fill = "none") print(fixed_plot)
内容的提问来源于stack exchange,提问作者velellavelella
相关产品推荐
相关产品推荐

