在R语言绘制的中国地图点数据中添加凸包的技术问询
给中国地图上的两组点数据添加凸包的解决方案
我来帮你搞定在R里给这两组野猪点数据生成凸包并叠加到中国地图上的问题!咱们一步步来:
1. 先合并数据集(方便后续处理凸包)
你之前是分开读两个CSV,现在咱们给每个数据集加个分组标记,然后合并成一个文件,这样后续计算凸包时能直接按组处理:
# 导入数据并添加分组列 sus_scrofa_lp <- read.csv(fileEncoding="UTF-8-BOM","C:/PhD/data/s-scrofa_lp.csv") sus_scrofa_lp$group <- "lp" # 标记第一组数据 sus_scrofa_ho <- read.csv(fileEncoding="UTF-8-BOM","C:/PhD/data/s-scrofa_ho.csv") sus_scrofa_ho$group <- "ho" # 标记第二组数据 # 合并成单个数据集 combined_data <- rbind(sus_scrofa_lp, sus_scrofa_ho)
2. 计算每组数据的凸包坐标
接下来用chull()函数计算每组点的凸包顶点。咱们可以用dplyr来分组处理,这样代码更简洁:
library(dplyr) # 定义函数:计算一组点的凸包坐标(确保多边形闭合) compute_convex_hull <- function(data) { hull_indices <- chull(data$lon, data$lat) hull_data <- data[hull_indices, ] # 闭合凸包:添加第一行坐标到最后一行,保证多边形完整 hull_data <- rbind(hull_data, hull_data[1, ]) return(hull_data) } # 按分组计算凸包 hull_data <- combined_data %>% group_by(group) %>% do(compute_convex_hull(.)) %>% ungroup()
3. 修改ggplot代码,叠加凸包到地图上
现在把凸包图层加到你原来的地图代码里,注意凸包的填充要设成半透明,避免挡住地图和点:
# 加载所需包 library(maptools) library(ggplot2) # 读取并处理中国地图数据 china_map1 <- readOGR(dsn="C:/PhD/data/bou2_4p.shp") china_map2 <- china_map1@data china_map2$NAME <- iconv(china_map2$NAME, from = 'GBK') china_map3 <- fortify(china_map1) # 绘制地图+点+凸包 ggplot() + # 绘制中国地图 geom_path(data = china_map3, aes(x = long, y = lat, group = group), color="grey40") + geom_polygon(data = china_map3, aes(x = long, y = lat, group = group), fill = 'beige') + # 绘制凸包(半透明填充,对应分组颜色) geom_polygon(data = hull_data, aes(x = lon, y = lat, group = group, fill = group), alpha = 0.2, color = NA) + # 绘制原始点数据 geom_point(data = sus_scrofa_lp, aes(lon, lat), alpha = 0.5, size = 0.5, color ="red") + geom_point(data = sus_scrofa_ho, aes(lon, lat), alpha = 0.5, size = 0.5, color ="blue") + # 设置坐标等比例,避免地图变形 coord_equal() + # 自定义凸包填充颜色(和点颜色对应) scale_fill_manual(values = c("lp" = "red", "ho" = "blue")) + # 去掉不必要的图例(如果不需要的话) guides(fill = "none")
关键说明:
- 合并数据集是为了用分组操作一次性处理两组点的凸包,比分开处理更高效;
chull()函数返回的是凸包顶点在原数据中的索引,我们需要提取这些索引对应的坐标,并且手动闭合多边形(把第一行坐标加到最后一行),这样ggplot才能正确绘制凸包;- 凸包的填充用
alpha=0.2设置半透明,既突出分布范围又不会挡住下面的点和地图。
内容的提问来源于stack exchange,提问作者Tom D




