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

如何用R的tmap库实现带引线的地图标注(类似ggrepel)

在tmap中实现带引线的防重叠标注(类似ggrepel/geom_sf_label_repel)

tmap本身没有内置的自动防重叠带引线标注功能,但可以通过结合ggrepel包计算标注位置,再在tmap中手动添加引线和文本,实现类似geom_sf_label_repel的效果。以下是针对实际shapefile的完整解决方案:

核心思路

利用ggrepel的geom_sf_label_repel自动计算不会重叠的标注坐标,然后将这些坐标提取出来,在tmap中用线段连接区域中心和标注位置,最后添加标注文本。

完整代码示例

1. 加载依赖包

library(tmap)
library(sf)
library(ggrepel)
library(dplyr)

2. 读取你的shapefile

替换为你的shapefile路径和文件名:

# 读取shapefile
shp_data <- st_read("your_shapefile_path/your_file.shp")

# 计算每个区域的中心坐标(用于连接引线)
shp_data <- shp_data %>%
  mutate(centroid = st_centroid(geometry))

3. 用ggrepel计算防重叠的标注位置

# 创建临时ggplot对象,用ggrepel计算标注位置
temp_plot <- ggplot(shp_data) +
  geom_sf() +
  geom_sf_label_repel(
    aes(label = 标注列名), # 替换成你要显示的标注字段
    nudge_x = 0.1, # 根据地图范围调整
    nudge_y = 0.1,
    force = 2, # 控制防重叠力度
    box.padding = 0.5
  )

# 提取ggrepel计算出的标注坐标
repel_coords <- layer_data(temp_plot, 2) %>%
  select(x, y, label) %>%
  st_as_sf(coords = c("x", "y"), crs = st_crs(shp_data))

4. 在tmap中绘制地图+带引线的标注

# 合并原始数据和标注坐标
shp_annotated <- shp_data %>%
  left_join(repel_coords, by = c("标注列名" = "label")) # 确保连接字段匹配

# 绘制tmap地图
tm_shape(shp_data) +
  tm_polygons() +
  # 添加引线:连接区域中心和标注位置
  tm_shape(shp_annotated) +
  tm_lines(
    col = "gray50",
    lwd = 0.8,
    data = st_sf(
      geometry = st_cast(st_combine(shp_annotated$centroid, shp_annotated$geometry.y), "LINESTRING")
    )
  ) +
  # 添加标注文本
  tm_shape(repel_coords) +
  tm_text(
    text = "label",
    col = "black",
    size = 0.8,
    fontface = "bold"
  )

优化技巧

  • 针对微小区域:可以先筛选出面积小于阈值的区域,单独调整ggrepel参数,给微小区域更大的偏移量避免拥挤:
# 筛选微小区域
small_areas <- shp_data %>%
  filter(st_area(geometry) < units::set_units(1, km^2)) # 替换成你的面积阈值

# 单独计算微小区域的标注位置
small_repel <- ggplot(small_areas) +
  geom_sf() +
  geom_sf_label_repel(aes(label = 标注列名), force = 5, nudge_x = 0.3) %>%
  layer_data(2) %>%
  select(x, y, label) %>%
  st_as_sf(coords = c("x", "y"), crs = st_crs(shp_data))

# 合并普通区域和微小区域的标注坐标
repel_coords <- repel_coords %>%
  filter(!label %in% small_repel$label) %>%
  bind_rows(small_repel)
  • 调整ggrepel的force、box.padding等参数,可优化标注分散程度,减少重叠。
  • 确保所有图层CRS一致,若有投影问题用st_transform统一转换。

内容的提问来源于stack exchange,提问作者Joke O.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:22:45