基于经纬度与肠球菌浓度的Heatmap形似Scatterplot,求解决方法
问题原因
你的数据是离散的经纬度采样点,而geom_tile()需要连续的网格状数据(每个网格单元对应一个固定位置),直接用原始离散点会让每个采样点生成一个极小的方块,视觉上就和散点图无异。
解决方法
根据需求选择两种常用方案:
方案1:插值生成连续热力图(推荐,展示浓度空间分布趋势)
通过插值将离散采样点转换为连续网格,用akima包实现示例如下:
- 安装并依赖包:
install.packages(c("ggplot2", "akima")) library(ggplot2) library(akima)
- 对数据做插值处理,生成网格数据集:
# 插值生成连续网格,nx/ny控制精细度,数值越大网格越密 interp_result <- interp(x = bacteria_data$Latitude, y = bacteria_data$Longitude, z = bacteria_data$Enterococci..cfu.100ml., nx = 100, ny = 100) # 转换为ggplot兼容的数据框格式 interp_df <- data.frame( Latitude = rep(interp_result$x, length(interp_result$y)), Longitude = rep(interp_result$y, each = length(interp_result$x)), Enterococci = as.vector(interp_result$z) )
- 绘制连续热力图:
ggplot(interp_df, aes(x = Latitude, y = Longitude, fill = Enterococci)) + geom_tile() + scale_fill_viridis_c(na.value = NA) + # 使用viridis配色,自动隐藏插值缺失区域 labs(x = "纬度", y = "经度", fill = "肠球菌浓度(cfu/100ml)") + theme_bw()
方案2:经纬度分箱聚合(保留离散采样特性)
如果不需要连续趋势,仅想将相近经纬度的采样点合并为方块,可对经纬度做分箱处理:
ggplot(bacteria_data, aes(x = Latitude, y = Longitude, fill = Enterococci..cfu.100ml.)) + # 设置tile的宽高,匹配你的经纬度数据精度 geom_tile(aes(width = 0.001, height = 0.001)) + labs(x = "纬度", y = "经度", fill = "肠球菌浓度(cfu/100ml)") + theme_bw() # 或者强制按固定数量分箱,聚合计算浓度均值 # ggplot(bacteria_data) + # aes(x = cut_interval(Latitude, n=20), # y = cut_interval(Longitude, n=20), # fill = mean(Enterococci..cfu.100ml.)) + # geom_tile() + # labs(x = "纬度区间", y = "经度区间", fill = "平均肠球菌浓度(cfu/100ml)")
补充提示
- 插值方案更适合呈现地理空间上的浓度变化趋势,是热力图的常规用法;
- 分箱方案保留原始采样的离散属性,适合观察局部区域的浓度聚合情况;
- 可根据你的经纬度数据范围,调整插值的
nx/ny参数或分箱数量,优化热力图的精度。
内容的提问来源于stack exchange,提问作者user20297887
相关产品推荐
相关产品推荐

