如何叠加两类六边形热力图:物种引入概率与已占领区域展示
解决叠加双六边形热力图的填充冲突问题
我懂你的困扰——你想在同一张图里同时展示物种引入概率的热力分布,以及已经被占领的黑色六边形区域,但默认情况下ggplot的填充比例尺只能有一个,第二个scale_fill会直接覆盖第一个的设置。这里有两种实用的解决方法:
方法1:用固定颜色覆盖已占领区域(无需额外包)
这个思路很直接:先绘制引入概率的热力图,再在上面叠加仅包含已占领区域的黑色六边形。因为我们给这些六边形设置固定填充色,不会用到映射的fill属性,所以不会和第一个热力图的比例尺冲突。
完整代码:
set.seed(123) # 确保结果可复现 df <- data.frame(latitude = rep(seq(1,10,1),10), longitude = rep(1:10, each=10), already_there = rbinom(100,1,0.1), introduction_probability = rbinom(100,100,0.5)/100) library(ggplot2) ggplot(data = df) + # 第一步:绘制引入概率的热力六边形 stat_summary_hex(aes(x = longitude, y = latitude, z = introduction_probability), binwidth = c(2,2)) + scale_fill_gradient2(mid="yellow", high="red", breaks=seq(0,1,0.25), limits=c(0,1), name = "Introduction Probability") + # 第二步:叠加已占领区域的黑色六边形(仅过滤出已占领的行) geom_hex(data = subset(df, already_there == 1), aes(x = longitude, y = latitude), binwidth = c(2,2), # 必须和前面的binwidth一致,保证对齐 fill = "black") + labs(title = "Species Introduction Probability & Occupied Zones", x = "Longitude", y = "Latitude")
方法2:用ggnewscale添加多个填充比例尺(支持双图例)
如果你想让已占领区域的黑色也单独显示在图例里,可以用ggnewscale包——它专门解决ggplot中同一美学属性需要多个比例尺的问题。
完整代码:
# 先安装包(仅第一次需要) install.packages("ggnewscale") library(ggplot2) library(ggnewscale) set.seed(123) df <- data.frame(latitude = rep(seq(1,10,1),10), longitude = rep(1:10, each=10), already_there = rbinom(100,1,0.1), introduction_probability = rbinom(100,100,0.5)/100) ggplot(data = df) + # 第一个图层:引入概率热力图 stat_summary_hex(aes(x = longitude, y = latitude, z = introduction_probability), binwidth = c(2,2)) + scale_fill_gradient2(mid="yellow", high="red", breaks=seq(0,1,0.25), limits=c(0,1), name = "Introduction Probability") + # 关键:开启新的填充比例尺上下文 new_scale_fill() + # 第二个图层:已占领区域的六边形 stat_summary_hex(aes(x = longitude, y = latitude, z = already_there), binwidth = c(2,2)) + scale_fill_gradient2(low = NA, high = "black", # 仅显示已占领(z=1)的黑色 breaks = c(0,1), limits = c(0,1), name = "Already Occupied") + labs(title = "Dual Hexbin Heatmap: Probability & Occupancy", x = "Longitude", y = "Latitude")
为什么你的原代码不行?
ggplot2的设计逻辑是:同一个美学属性(比如fill)只能绑定一个比例尺。当你添加第二个scale_fill_gradient2时,它会完全替换掉第一个的设置,导致只有最后一个比例尺生效。上面两种方法要么避开了重复映射fill,要么用工具包扩展了ggplot的比例尺能力。
内容的提问来源于stack exchange,提问作者samp
相关产品推荐
相关产品推荐

