You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggplot2/ggrepel将点标签置于多边形外并扩大多边形?

嘿,针对你提出的两个ggplot2地图可视化问题,我整理了具体的解决方案和修改后的代码,一起来看看吧:

问题1:分离重叠的点

你提到的“扩大多边形以分离重叠点”其实不是最优选择——这样会扭曲澳大利亚的地图形状,破坏空间数据的准确性。更合适的方式是让重叠的采样点自动分散开,我们可以借助ggrepel包的geom_point_repel来实现,它会在不改变原始坐标逻辑的前提下,调整重叠点的位置,让每个点都清晰可见:

  • 核心修改:用geom_point_repel()替换普通的geom_point(),并设置seed参数保证结果可重复,避免每次绘图点位置随机变化。
问题2:将所有标签置于多边形外部

要让城市标签都显示在澳大利亚地图的外部,我们可以从四个方面调整:

  1. 先过滤掉points数据中空的城市标签(避免无效的空标签干扰可视化);
  2. 增大geom_label_repel的推离力度(force参数),让标签主动远离地图区域;
  3. 针对性微调个别城市标签的偏移量(比如霍巴特、珀斯这类边缘城市);
  4. 扩大坐标轴范围,给外部标签留出足够的显示空间;
  5. 改用coord_sf()处理空间数据(比coord_fixed更适配空间对象,地图显示更精准)。

修改后的完整代码

library(ggplot2)
library(ggrepel)
library(sf) # 用于转换sp对象为sf格式,适配ggplot2的空间绘图

# 原始采样点数据
points <- structure(list(city = structure( c( 9L, 1L, 1L, 1L, 7L, 1L, 3L, 1L, 1L, 1L, 2L, 1L, 1L, 8L, 1L, 1L, 5L, 1L, 4L, 1L, 1L, 6L), .Label = c("", "Adelaide", "Brisbane", "Canberra", "Darwin", "Hobart", "Melbourne", "Perth", "Sydney"), class = "factor"), site = structure(c(19L, 20L, 21L, 22L, 14L, 15L, 5L, 6L, 7L, 8L, 2L, 3L, 4L, 16L, 17L, 18L, 12L, 13L, 9L, 10L, 11L, 1L), .Label = c("", "ADL1", "ADL2", "ADL3", "BNE1", "BNE2", "BNE3", "BNE4", "CBR1", "CBR2", "CBR3", "DRW1", "DRW2", "MEL1", "MEL2", "PER1", "PER2", "PER3", "SYD1", "SYD2", "SYD3", "SYD4"), class = "factor"), station = structure(c(8L, 5L, 12L, 16L, 10L, 3L, 22L, 18L, 17L, 20L, 2L, 14L, 11L, 4L, 7L, 19L, 15L, 21L, 6L, 9L, 13L, 1L), .Label = c("", "Adelaide CBD", "Alphington", "Caversham", "Chullora", "Civic", "Duncraig", "Earlwood", "Florey", "Footscray", "Le Fevre 2", "Liverpool", "Monash", "Netley", "Palmerston", "Richmond", "Rocklea", "South Brisbane", "South Lake", "Springwood", "Winnellie", "Woolloongabba"), class = "factor"), latitude = c(-33.9178, -33.8939, -33.9328, -33.6183, -37.8048, -37.7783, -27.4975, -27.4848, -27.5358, -27.6125, -34.9289, -34.9438, -34.7913, -31.9505, NA, NA, -12.50779, -12.4243233, -35.285307, -35.220606, -35.418302, -42.8821), longitude = c(151.1347, 151.045, 150.9058, 150.7458, 144.8727, 145.0306, 153.035, 153.0321, 152.9934, 153.1356, 138.6011, 138.5492, 138.498, 115.8605, NA, NA, 130.94853, 130.8933502, 149.131579, 149.043539, 149.094018, 147.3272)), .Names = c("city", "site", "station", "latitude", "longitude"), class = "data.frame", row.names = c(NA, -22L))

# 读取空间数据并转换为sf格式(比sp对象更适配ggplot2)
AUS <- readRDS("gadm36_AUS_1_sp.rds")
AUS_sf <- st_as_sf(AUS)

# 过滤掉空的城市标签,避免无效标签干扰
points_filtered <- points[!is.na(points$city) & points$city != "", ]

ggplot() +
  # 绘制澳大利亚地图多边形
  geom_sf(data = AUS_sf, fill = NA, color = "black", size = 0.1) +
  # 用geom_point_repel自动分离重叠的采样点
  geom_point_repel(data = points, aes(x = longitude, y = latitude), 
                   color = "blue", size = 0.5, seed = 123, # seed保证结果可重复
                   box.padding = 0.2, point.padding = 0.1) +
  # 绘制城市标签,设置参数让标签显示在地图外部
  geom_label_repel(data = points_filtered, aes(x = longitude, y = latitude, label = city),
                   box.padding = 1.5, point.padding = 1.2,
                   force = 8, # 增大推离力度,让标签远离地图多边形
                   # 针对边缘城市手动微调偏移量
                   nudge_y = ifelse(points_filtered$city == "Hobart", -2, 0),
                   nudge_x = ifelse(points_filtered$city == "Perth", -3, 0),
                   segment.color = "gray50") +
  # 用coord_sf处理空间坐标,替代coord_fixed,显示更精准
  coord_sf(xlim = c(95, 185), ylim = c(-65, 5)) + # 扩大坐标轴范围,给标签留足空间
  theme_classic() +
  theme(axis.text = element_text(size = 8)) # 调整坐标轴文字大小,避免拥挤

关键修改说明

  • 空间对象转换:用st_as_sf(AUS)将sp格式转为sf格式,搭配geom_sf绘制多边形,代码更简洁且空间坐标更准确;
  • 重叠点分离:geom_point_repel自动调整重叠点位置,seed参数确保绘图结果可复现;
  • 标签外部显示:通过force参数增大推离力度,结合针对性的nudge_x/nudge_y微调,再配合扩大的坐标轴范围,确保所有标签都显示在地图外部;
  • 空标签过滤:提前移除无效的空城市标签,避免不必要的绘图干扰。

内容的提问来源于stack exchange,提问作者Alma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:39:32