如何在R中限制stat_density_2d分析范围至底层JPEG中的多边形?
解决步骤
1. 给图片和多边形建立统一坐标系
因为你的JPEG无关联坐标,首先要给图片、多边形、分析数据建立一致的坐标体系:
- 用
ggplot2的annotation_custom()导入图片,手动设定x、y轴的范围(比如x取0-100,y取0-100,根据图片比例调整)。 - 手动标记多边形顶点坐标:可以借助图片编辑工具(如GIMP)标记顶点相对位置,转换成你设定的坐标系数值。
2. 对齐数据集到目标坐标系
把你的分析数据集的x、y值,通过缩放、平移转换到和图片、多边形一致的坐标系中,确保数据点的分布和图片上的视觉位置匹配。
3. 约束密度估计在多边形内(核心步骤)
要让密度分析仅针对多边形内的区域,而非全局计算后裁剪,可按以下两种方式实现:
方式一:用ks包做受限区域核密度估计
这个包支持在自定义多边形内计算密度,结果更精准:
library(sf) library(ks) library(ggplot2) library(magick) # 1. 构建多边形空间对象 poly_coords <- data.frame(x = c(20, 80, 80, 20), y = c(20, 20, 80, 80)) # 替换成你的多边形顶点 poly_sf <- st_polygon(list(as.matrix(poly_coords))) %>% st_sfc() %>% st_sf() # 2. 筛选多边形内的数据点 data_sf <- st_as_sf(your_dataset, coords = c("x", "y")) # your_dataset是你的分析数据 data_in_poly <- st_filter(data_sf, poly_sf) coords_in_poly <- st_coordinates(data_in_poly) # 3. 在多边形内计算密度 poly_kde <- kde(x = coords_in_poly, H = Hpi(coords_in_poly), bbox = st_bbox(poly_sf), cont = c(50, 95)) kde_df <- data.frame(poly_kde$eval.points[[1]], poly_kde$eval.points[[2]], density = poly_kde$estimate) # 4. 绘图叠加 ggplot() + annotation_custom(grid::rasterGrob(image_read("your_image.jpg")), xmin = 0, xmax = 100, ymin = 0, ymax = 100) + geom_sf(data = poly_sf, fill = NA, color = "red") + geom_contour(data = kde_df, aes(x = X1, y = X2, z = density), color = "blue") + coord_sf(xlim = c(0,100), ylim = c(0,100))
方式二:用ggplot原生函数结合数据筛选
如果不想额外安装包,可先筛选多边形内的数据,再做密度估计:
library(ggplot2) library(sf) library(magick) # 1. 筛选多边形内的数据点 poly_coords <- data.frame(x = c(20, 80, 80, 20), y = c(20, 20, 80, 80)) poly_sf <- st_polygon(list(as.matrix(poly_coords))) %>% st_sfc() %>% st_sf() data_in_poly <- st_filter(st_as_sf(your_dataset, coords = c("x", "y")), poly_sf) %>% st_drop_geometry() # 2. 绘图,用多边形做蒙版限制显示 ggplot() + annotation_custom(grid::rasterGrob(image_read("your_image.jpg")), xmin = 0, xmax = 100, ymin = 0, ymax = 100) + geom_polygon(data = poly_coords, aes(x = x, y = y), fill = NA, color = "red") + stat_density_2d(data = data_in_poly, aes(x = x, y = y, color = stat(level)), geom = "contour", na.rm = TRUE) + coord_cartesian(xlim = range(poly_coords$x), ylim = range(poly_coords$y))
内容的提问来源于stack exchange,提问作者user20601386
相关产品推荐
相关产品推荐

