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

R 4.3.2中不用ggsn,ggmap+ggspatial添加比例尺报错求助

解决ggspatial::annotation_scale在ggmap生成的地图上报错问题

问题原因

你遇到的错误源于ggmap返回的ggplot对象使用旧版CoordMap坐标系,而ggspatial::annotation_scale对该坐标系的支持不完善,无法自动计算比例尺参数。


解决方案1:改用sf格式绘制地图(推荐)

将地图转换为sf对象,使用ggplot2的coord_sf()坐标系,让ggspatial工具能正确识别并计算比例尺:

library(ggplot2)
library(ggmap)
library(ggspatial)
library(sf)

# 获取地图并转换为sf格式
cy <- c(left = 32.2, bottom = 34.5, right = 34.8, top = 35.8)
CY_map_sf <- get_stadiamap(cy, zoom = 10, maptype = "stamen_terrain") %>% 
  ggmap::get_map_data() %>% 
  sf::st_as_sf(coords = c("lon", "lat"), crs = 4326) %>% 
  sf::st_bbox() %>% 
  sf::st_as_sfc() %>% 
  sf::st_sf()

# 准备点位数据并转为sf格式
long  <- c(33.0,  33.5)
lat <- c(34.75, 35.0)
df <- data.frame(long, lat) %>% 
  sf::st_as_sf(coords = c("long", "lat"), crs = 4326)

# 绘制地图并添加图层
ggCY <- ggplot() +
  geom_sf(data = CY_map_sf, fill = "transparent") +
  ggspatial::annotation_map_tile(type = "stamen_terrain", zoom = 10, cachedir = tempdir()) +
  geom_sf(data = df, color = "red", size = 3.5) +
  xlab("Longitude (°E)") + ylab("Latitude (°S)") +
  theme(axis.text.x  = element_text(size = 20),
        axis.text.y  = element_text(size = 20),
        axis.title.x = element_text(size = 26),
        axis.title.y = element_text(size = 26),
        legend.title=element_text(size=15),
        legend.text=element_text(size=15),
        legend.position = c(0.93, 0.13)) +
  scale_color_gradientn(colours = c('#5749a0', '#0f7ab0', '#00bbb1',
                                     '#bef0b0', '#fdf4af', '#f9b64b',
                                     '#ec840e', '#ca443d', '#a51a49'))

# 添加指北针和比例尺
ggCY_final <- ggCY +
  ggspatial::annotation_north_arrow(
    location = "tl", 
    pad_x = unit(0.4, "in"), 
    pad_y = unit(0.4, "in"),
    style = ggspatial::north_arrow_nautical(
      fill = c("grey40", "white"),
      line_col = "grey20",
      text_family = "ArcherPro Book"
    )
  ) +
  ggspatial::annotation_scale(location = "bl", width_hint = 0.5)

ggCY_final

说明:使用annotation_map_tile直接加载Stamen瓦片,配合sf坐标系,可让ggspatial自动适配比例尺计算逻辑。


解决方案2:手动添加比例尺(适配原ggmap代码)

如果不想切换sf格式,可通过计算经纬度与实际距离的转换关系,手动绘制比例尺:

library(ggplot2)
library(ggmap)
library(ggspatial)
library(grid)

# 原代码生成地图
cy <- c(left = 32.2, bottom = 34.5, right = 34.8, top = 35.8)
CY_map <- get_stadiamap(cy, zoom = 10, maptype = "stamen_terrain") %>% ggmap()

long  <- c(33.0,  33.5)
lat <- c(34.75, 35.0)
df <- data.frame(long, lat)

ggCY <- CY_map +       
  geom_point(data = df, aes(x = long, y = lat), col="red", size = 3.5) + 
  xlab("Longitude (°E)") + ylab("Latitude (°S)") +
  theme(axis.text.x  = element_text(size = 20),
        axis.text.y  = element_text(size = 20),
        axis.title.x = element_text(size = 26),
        axis.title.y = element_text(size = 26),
        legend.title=element_text(size=15),
        legend.text=element_text(size=15),
        legend.position = c(0.93, 0.13)) +   
  scale_color_gradientn(colours = c('#5749a0', '#0f7ab0', '#00bbb1',
                                     '#bef0b0', '#fdf4af', '#f9b64b',
                                     '#ec840e', '#ca443d', '#a51a49')) +
  ggspatial::annotation_north_arrow(
    location = "tl", 
    pad_x = unit(0.4, "in"), 
    pad_y = unit(0.4, "in"),
    style = ggspatial::north_arrow_nautical(
      fill = c("grey40", "white"),
      line_col = "grey20",
      text_family = "ArcherPro Book"
    )
  )

# 计算当前纬度下,10公里对应的经度差(35°纬度处,1经度≈88.5公里)
km_per_degree_lon <- 111.32 * cos(35 * pi/180)
degree_for_10km <- 10 / km_per_degree_lon

# 创建自定义比例尺grob
scale_grob <- grobTree(
  segmentsGrob(
    x0 = unit(0.05, "npc"), y0 = unit(0.05, "npc"),
    x1 = unit(0.05 + degree_for_10km/(cy["right"] - cy["left"]), "npc"), y1 = unit(0.05, "npc"),
    gp = gpar(lwd = 2, col = "black")
  ),
  textGrob(
    label = "10 km",
    x = unit(0.05 + degree_for_10km/(2*(cy["right"] - cy["left"])), "npc"),
    y = unit(0.03, "npc"),
    gp = gpar(fontsize = 12)
  )
)

# 添加手动比例尺
ggCY_final <- ggCY + annotation_custom(scale_grob)
ggCY_final

说明:通过地理公式计算经纬度与公里数的转换关系,手动绘制固定长度的比例尺,无需修改原有ggmap绘图逻辑。


内容的提问来源于stack exchange,提问作者ΚΩΝΣΤΑΝΤΙΝΟΣ ΠΑΝΑΓΙΩΤΟΥ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:58:12