如何使用sf包围绕多边形放置地理坐标标签?
问题描述
我绘制了如下多边形:
library(ggplot2) library(sf) #> Linking to GEOS 3.11.1, GDAL 3.6.2, PROJ 9.1.1; sf_use_s2() is TRUE poly <- st_polygon(list(rbind( c(-90, 70), c(-40, 70), c(-40, 74), c(-90, 74), c(-90, 70) ))) |> st_sfc() |> st_segmentize(5) |> st_set_crs(4326) |> st_as_sf() |> st_transform(3413) |> st_cast("POLYGON") ggplot() + geom_sf(data = poly) + theme( panel.background = element_blank() )

请问是否可以设置坐标标签的位置,使其贴合多边形的形状(而非绘图区域的形状)?
解决方案
可以通过提取多边形边界坐标、手动放置标签的方式实现,以下是两种可行方法:
方法1:提取边缘点添加对应标签
先从多边形中提取边界坐标,筛选出左右两侧、上下边缘的关键点,将经纬度坐标转换后作为标签放置在贴合边缘的位置:
library(ggplot2) library(sf) library(dplyr) # 生成原始多边形 poly <- st_polygon(list(rbind( c(-90, 70), c(-40, 70), c(-40, 74), c(-90, 74), c(-90, 70) ))) |> st_sfc() |> st_segmentize(5) |> st_set_crs(4326) |> st_as_sf() |> st_transform(3413) |> st_cast("POLYGON") # 提取多边形边界坐标并转换为数据框 poly_coords <- st_coordinates(poly) |> as.data.frame() |> rename(x = X, y = Y) # 筛选左右两侧的边缘点 left_edge <- poly_coords |> filter(x == min(x)) right_edge <- poly_coords |> filter(x == max(x)) # 筛选上下边缘的点 bottom_edge <- poly_coords |> filter(y == min(y)) top_edge <- poly_coords |> filter(y == max(y)) # 生成x轴标签数据(转换回WGS84经纬度) x_label_data <- bind_rows( left_edge |> slice(seq(1, nrow(left_edge), length.out = 3)) |> mutate(label = round(st_transform(st_sfc(st_point(c(x,y)), 3413), 4326)[[1]][1], 1)), right_edge |> slice(seq(1, nrow(right_edge), length.out = 3)) |> mutate(label = round(st_transform(st_sfc(st_point(c(x,y)), 3413), 4326)[[1]][1], 1)) ) # 生成y轴标签数据 y_label_data <- bind_rows( bottom_edge |> slice(seq(1, nrow(bottom_edge), length.out = 3)) |> mutate(label = round(st_transform(st_sfc(st_point(c(x,y)), 3413), 4326)[[1]][2], 1)), top_edge |> slice(seq(1, nrow(top_edge), length.out = 3)) |> mutate(label = round(st_transform(st_sfc(st_point(c(x,y)), 3413), 4326)[[1]][2], 1)) ) # 绘图:隐藏默认坐标轴,添加自定义标签 ggplot() + geom_sf(data = poly) + # 添加x轴标签(偏移避免覆盖多边形) geom_text(data = x_label_data, aes(x = x - 50000, y = y, label = label), size = 3) + # 添加y轴标签 geom_text(data = y_label_data, aes(x = x, y = y + 30000, label = label), size = 3) + # 隐藏默认坐标轴元素 theme( panel.background = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank() )
方法2:使用annotation_custom手动定位标签
通过st_bbox获取多边形的边界范围,用annotation_custom将标签直接放置在贴合边缘的位置:
library(ggplot2) library(sf) library(grid) # 生成原始多边形(代码同前) poly <- st_polygon(list(rbind( c(-90, 70), c(-40, 70), c(-40, 74), c(-90, 74), c(-90, 70) ))) |> st_sfc() |> st_segmentize(5) |> st_set_crs(4326) |> st_as_sf() |> st_transform(3413) |> st_cast("POLYGON") # 获取多边形边界框 poly_bbox <- st_bbox(poly) ggplot() + geom_sf(data = poly) + # 左侧x轴标签 annotation_custom( grob = textGrob(label = "-90", rot = 90, size = 10), xmin = poly_bbox[1] - 60000, xmax = poly_bbox[1] - 60000, ymin = poly_bbox[2], ymax = poly_bbox[4] ) + # 右侧x轴标签 annotation_custom( grob = textGrob(label = "-40", rot = 90, size = 10), xmin = poly_bbox[3] + 60000, xmax = poly_bbox[3] + 60000, ymin = poly_bbox[2], ymax = poly_bbox[4] ) + # 底部y轴标签 annotation_custom( grob = textGrob(label = "70", size = 10), xmin = poly_bbox[1], xmax = poly_bbox[3], ymin = poly_bbox[2] - 40000, ymax = poly_bbox[2] - 40000 ) + # 顶部y轴标签 annotation_custom( grob = textGrob(label = "74", size = 10), xmin = poly_bbox[1], xmax = poly_bbox[3], ymin = poly_bbox[4] + 40000, ymax = poly_bbox[4] + 40000 ) + theme( panel.background = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), axis.title = element_blank() )
注意事项
- 偏移量(如
x - 50000)需要根据多边形的实际尺寸调整,确保标签不覆盖图形; - 标签显示的是转换回WGS84的经纬度,若需显示投影坐标系的坐标,可直接使用
x或y值。
内容的提问来源于Stack Exchange,提问作者Philippe Massicotte
相关产品推荐
相关产品推荐

