如何重新排序X、Y坐标点以形成适配ggplot与sf的闭合多边形?
问题:如何自动排序混乱的坐标点以生成闭合多边形?
我有一组用于勾勒地图区域的X、Y坐标点,想用这些点定义多边形,通过ggplot结合simple features(sf)库绘制。但点的顺序混乱,连线无法形成闭合形状,试过geom_line和geom_path函数,有没有无需手动排序就能整理点顺序的方法?
以下是可复现示例:“good circle”是预期效果,“bad circle”是当前状态,二者坐标点完全相同,但“bad circle”的点顺序混乱,无法生成闭合图形。
预期效果(有序坐标)代码:
library(dplyr) library(ggplot2) library(sf) rad <- 1 # 补充缺失的半径定义 x_coords <- rad * cos(seq(0, (2 * pi), (pi / 6))) y_coords <- rad * sin(seq(0, (2 * pi), (pi / 6))) perimeter <- as.matrix(rbind(cbind(x_coords, y_coords), c(x_coords[1], y_coords[1]))) good_circle = st_multipolygon(list(list(perimeter))) ggplot() + geom_sf(data = good_circle, fill = "blue") + ggtitle("good circle")

当前混乱状态代码:
bad_circle <- slice(data.frame(perimeter), sample(1:n())) ggplot(bad_circle, aes(x = V1, y = V2)) + geom_point() + geom_line() + ggtitle("bad circle")

解决方案
方法1:基于极坐标角度排序(适用于凸多边形)
通过计算每个点相对于坐标中心的角度,按角度排序即可让点按顺时针/逆时针排列,形成闭合多边形。
# 处理混乱的坐标点 sorted_circle <- bad_circle %>% # 计算所有点的中心坐标 mutate( center_x = mean(V1), center_y = mean(V2), # 计算点相对于中心的极角 angle = atan2(V2 - center_y, V1 - center_x) ) %>% # 按角度从小到大排序 arrange(angle) %>% # 添加第一个点到末尾,确保多边形闭合 bind_rows(slice(., 1)) # 转为sf多边形并绘制 sorted_polygon <- st_multipolygon(list(list(as.matrix(sorted_circle[, c("V1", "V2")])))) ggplot() + geom_sf(data = sorted_polygon, fill = "lightblue") + ggtitle("sorted circle")
方法2:利用凸包自动排序(仅适用于凸多边形)
如果你的目标区域是凸多边形,可以用sf的凸包函数自动整理点的顺序:
# 将混乱的点转为sf点对象 bad_points <- st_as_sf(bad_circle, coords = c("V1", "V2")) # 生成凸包(自动排序点) convex_hull <- st_convex_hull(st_union(bad_points)) # 绘制结果 ggplot() + geom_sf(data = convex_hull, fill = "lightgreen") + ggtitle("convex hull circle")
额外说明
- 若处理的是凹多边形,上述两种方法可能失效,此时可以使用
alphahull包的ashape函数实现更复杂的点排序(需要调整alpha参数匹配多边形形状)。 - 无论哪种方法,都要确保最后重复第一个点,保证多边形闭合。
内容的提问来源于stack exchange,提问作者L_Iguana
相关产品推荐
相关产品推荐

