You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在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

火山引擎 最新活动