在sf对象下方绘制静态底图时的ggmap与ggplot2调用问题
解决ggmap与sf/ggplot2结合绘制底图的问题
看起来你在尝试用ggmap给sf对象添加静态底图用于打印时,遇到了get_map报错、无法将ggmap图层与geom_sf的ggplot对象链式调用这两个核心问题。我来一步步帮你解决这些问题:
一、先解决get_map的报错问题
现在ggmap调用Google地图需要配置API密钥,且Google的免费额度有限,更适合静态打印的替代方案是使用Stamen地图——不需要密钥就能直接调用:
library(sf) library(ggplot2) library(ggmap) # 读取nc的sf示例数据 nc <- st_read(system.file("shape/nc.shp", package="sf")) # 基于nc数据的边界范围定位底图,避免手动输入地点名 nc_bbox <- st_bbox(nc) %>% as.character() %>% setNames(c("left", "bottom", "right", "top")) # 获取Stamen静态底图,可选maptype有toner-lite/terrain/watercolor等 nc_map <- get_map(location = nc_bbox, source = "stamen", maptype = "toner-lite", zoom = 7)
如果一定要用Google地图,需要先到Google Cloud平台申请API密钥,再通过register_google(key = "你的密钥")注册后调用get_map。
二、解决ggmap与geom_sf的链式调用问题
ggmap默认使用WGS84坐标系(EPSG:4326),而nc的sf数据默认是NAD27(EPSG:4267),两者坐标系不匹配会导致图层错位;另外ggmap的图层有自己的美学映射,需要手动关闭继承才能和geom_sf兼容:
# 将nc数据转换为和ggmap一致的WGS84坐标系 nc_wgs84 <- st_transform(nc, crs = 4326) # 计算转换后的区域中心点 nc_centers <- st_centroid(nc_wgs84) # 链式调用绘制底图+sf边界+中心点 ggmap(nc_map) + geom_sf(data = nc_wgs84, fill = NA, color = "darkred", size = 0.8, inherit.aes = FALSE) + # 必须加此参数,避免继承ggmap的错误映射 geom_sf(data = nc_centers, color = "blue", size = 2, inherit.aes = FALSE) + labs(title = "North Carolina with Stamen Toner-Lite Base Map")
补充:更稳定的替代方案——ggplot2原生瓦片图层
如果你不想依赖ggmap,ggplot2从3.3.0版本开始支持直接添加地图瓦片,和sf的兼容性更好,完全适配链式调用:
library(ggplot2) library(sf) nc_wgs84 <- st_transform(nc, crs = 4326) nc_centers <- st_centroid(nc_wgs84) ggplot() + annotation_map_tile(type = "stamen_toner_lite", # 支持多种瓦片类型 zoom = 7) + geom_sf(data = nc_wgs84, fill = NA, color = "darkred", size = 0.8) + geom_sf(data = nc_centers, color = "blue", size = 2) + coord_sf(crs = st_crs(4326)) + # 确保坐标系统一 labs(title = "North Carolina with ggplot2 Annotation Tile")
内容的提问来源于stack exchange,提问作者Tdebeus
相关产品推荐
相关产品推荐

