R中使用sf库st_centroid绘制GIS多边形标签全部重叠如何解决
问题原因
标签重叠的核心问题是手动提取的质心坐标和最终绘图坐标系不匹配:
- 你调用
st_centroid提取X、Y坐标时,使用的是provshp文件原始自带的坐标系 - 后续
coord_sf指定了crs=st_crs(3310),ggplot仅会自动转换sf对象geometry列的投影,你单独存储的X、Y属于普通数值列,不会被自动转换投影,导致原始坐标系下的坐标放在3310坐标系中全部挤在同一位置。
另外你代码里的aes(fill="blue")写法有误,固定填充值放在aes内会被识别为分类变量,不会渲染为蓝色还会生成多余图例,固定值需放在aes外。
解决方法
方法1:先统一坐标系再计算质心
先把所有空间数据统一转换为EPSG:3310投影,再提取质心坐标,保证坐标和绘图坐标系完全匹配:
library("ggplot2") library("sf") library("dplyr") # 加载dplyr用管道符,你也可以用嵌套写法 sf::sf_use_s2(FALSE) # 读取数据后先统一转换为目标投影3310 world <- st_read("C:/prgrm/gis/source/10m_land_and_islands.shp") %>% st_transform(3310) prov <- st_read("C:/prgrm/gis/edited ncm/ncm_provinces.shp") %>% st_transform(3310) # 再计算质心、提取坐标 prov <- cbind(prov, st_coordinates(st_centroid(prov))) ggplot(data = world) + geom_sf() + geom_sf(data=prov, fill="blue") + geom_text(data=prov, aes(X,Y, label=provname_r), size=5) + coord_sf(xlim=c(-2000000,1000000),ylim=c(-1500000, 3000000)) # 已提前转好投影,coord_sf无需重复指定crs
方法2:直接用geom_sf_text自动处理(更简便)
sf配套的ggplot图层geom_sf_text/geom_sf_label会自动识别sf对象的质心,且自动匹配绘图坐标系,不需要手动提取坐标:
library("ggplot2") library("sf") sf::sf_use_s2(FALSE) world <- st_read("C:/prgrm/gis/source/10m_land_and_islands.shp") prov <- st_read("C:/prgrm/gis/edited ncm/ncm_provinces.shp") ggplot(data = world) + geom_sf() + geom_sf(data=prov, fill="blue") + # 直接调用geom_sf_text,无需提前计算质心、提取坐标 geom_sf_text(data=prov, aes(label=provname_r), size=5) + coord_sf(xlim=c(-2000000,1000000),ylim=c(-1500000, 3000000), crs=st_crs(3310))
内容的提问来源于stack exchange,提问作者Sjiveru
相关产品推荐
相关产品推荐

