如何用ggplot2绘制GAM结果的等高线与热力图(移除无数据区)
解决方案
要移除无实测点区域的热力图与等高线,只需保留原始x-y数据凸包范围内的预测点即可,无需修改GAM模型结构。具体实现步骤如下:
1. 计算原始数据的凸包并过滤预测点
凸包能精准圈出所有实测点覆盖的边界区域,超出该范围的点即为无数据的空白区域。使用chull()获取凸包顶点,再通过point.in.polygon()筛选出凸包内的预测点:
# 加载所需包(若未安装sp包先执行 install.packages("sp")) library(sp) # 计算原始x-y数据的凸包顶点索引 hull_idx <- chull(df$x, df$y) # 提取凸包的顶点坐标 hull_poly <- df[hull_idx, c("x", "y")] # 判断每个预测点是否在凸包内(返回1表示在内部或边界上) df_pred$in_hull <- point.in.polygon(df_pred$x, df_pred$y, hull_poly$x, hull_poly$y) == 1 # 过滤出凸包内的预测点 df_pred_filtered <- df_pred[df_pred$in_hull, ]
2. 基于过滤后的数据绘图
将原代码中的df_pred替换为df_pred_filtered,即可仅在有实测点的区域绘制热力图与等高线:
gg <- ggplot() + geom_tile(data=df_pred_filtered, aes(x=x, y=y, fill = fit)) + geom_point(data=df, aes(x=x, y=y)) + scale_fill_distiller(palette = "YlGnBu") + geom_contour(data=df_pred_filtered, aes(x=x, y=y, z = fit), colour = "white") print(gg)
额外说明
- 该方法适配你当前的可加性GAM模型(
z ~ s(x) + s(y)),无需将模型改为交互项s(x,y) - 若需要更贴合数据分布的边界(而非凸包),可尝试核密度估计(如
MASS::kde2d)过滤预测点,但凸包方案更简单高效
内容的提问来源于stack exchange,提问作者imtaiky
相关产品推荐
相关产品推荐

