ggplot2地图优化:多边形标签外置、配色图例及轴标签修改求助
问题与解决方案
需求说明
- 将多边形标签置于外部,仅保留数据点在多边形内
- 为多边形添加配色,创建标题为“Statistical Areas”的图例,对应909、910、911的颜色
- 将x轴改为“Longitude”,y轴改为“Latitude”
遇到的问题
使用ggrepel包实现标签外置时,出现geom_text_repel缺少x、y、label美学属性的错误,同时收到st_point_on_surface不适用于经纬度数据的警告。
初始代码
library(ggplot2) ggplot(data = stats_shapefile) + geom_sf(fill = 'White') + geom_sf(data = samples_sf) scale_fill_discrete("Statistical Area") + geom_sf_text( aes(label = Statistica), size = 8 / .pt, position = "identity" )
尝试的ggrepel代码
library(ggrepel) ggplot(data = stats_shapefile) + geom_sf(fill = 'White') + geom_sf(data = samples_sf) + scale_fill_discrete("Statistical Area") + geom_sf_text(aes(label = Statistica), size = 8 / .pt) + geom_text_repel( nudge_x = ifelse(stats_shapefile$Statistica == 6, 1, 0), nudge_y = ifelse(stats_shapefile$Statistica == 6, 8, 0) )
报错信息
Error in
geom_text_repel():
! Problem while setting up geom.
ℹ Error occurred in the 3rd layer.
Caused by error incompute_geom_1():
!geom_text_repel()requires the following missing aesthetics: x, y, and label.
Runrlang::last_trace()to see where the error occurred.
Warning message:
In st_point_on_surface.sfc(sf::st_zm(x)) :
st_point_on_surface may not give correct results for longitude/latitude data
回溯信息
rlang::last_trace() <error/rlang_error> Error in `geom_text_repel()`: ! Problem while setting up geom. ℹ Error occurred in the 3rd layer. Caused by error in `compute_geom_1()`: ! `geom_text_repel()` requires the following missing aesthetics: x, y, and label. --- Backtrace: ▆ 1. ├─base (local) `<fn>`(x) 2. └─ggplot2 (local) `print.ggplot2::ggplot`(x) 3. ├─ggplot2::ggplot_build(x) 4. └─ggplot2 (local) `ggplot_build.ggplot2::ggplot`(x) 5. └─ggplot2:::by_layer(...) 6. ├─rlang::try_fetch(...) 7. │ ├─base::tryCatch(...) 8. │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 9. │ │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 10. │ │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 11. │ └─base::withCallingHandlers(...) 12. └─ggplot2 (local) f(l = layers[[i]], d = data[[i]]) 13. └─l$compute_geom_1(d) 14. └─ggplot2 (local) compute_geom_1(..., self = self)
解决方案代码
library(ggplot2) library(ggrepel) library(sf) # 提前计算多边形中心点,解决经纬度警告问题 stats_shapefile <- stats_shapefile %>% mutate( centroid = st_centroid(geometry, of_largest_polygon = TRUE), lon = st_coordinates(centroid)[,1], lat = st_coordinates(centroid)[,2] ) ggplot(data = stats_shapefile) + # 多边形按统计编号配色 geom_sf(aes(fill = factor(Statistica))) + # 保留内部数据点 geom_sf(data = samples_sf, color = "black", size = 2) + # 设置图例标题 scale_fill_discrete(name = "Statistical Areas") + # 外置标签,用提前计算的经纬度定位 geom_text_repel( aes(x = lon, y = lat, label = Statistica), size = 8 / .pt, nudge_x = 0.5, # 可根据实际地图范围调整偏移量 nudge_y = 0.5, min.segment.length = 0 # 强制显示标签与多边形的连接线 ) + # 修改坐标轴名称 labs(x = "Longitude", y = "Latitude") + theme_minimal()
关键修改说明
- 解决
geom_text_repel报错:
这个图层不支持直接读取sf的geometry,必须显式传入x、y坐标和label。通过st_centroid计算多边形中心点的经纬度,作为标签的定位依据。 - 处理经纬度警告:
用st_centroid替代默认的st_point_on_surface,后者不适用于地理坐标系(经纬度)数据,st_centroid更适配这类数据的中心点计算。 - 实现多边形配色与图例:
在geom_sf中添加aes(fill = factor(Statistica)),把统计区域编号映射为填充色;通过scale_fill_discrete设置图例标题为“Statistical Areas”。 - 标签外置:
删除原有的geom_sf_text,改用geom_text_repel,通过nudge_x/nudge_y调整标签偏移量,确保标签在多边形外部,min.segment.length = 0保证标签和多边形的连线始终显示。 - 修改坐标轴标签:
直接用labs函数替换默认的坐标轴名称。
内容的提问来源于stack exchange,提问作者Angela Russell
相关产品推荐
相关产品推荐

