ggmap与sf绘制点位偏移旧bug是否仍未解决?有无可行规避方案?
ggmap与sf结合点位偏移问题:现状及解决办法
这个因坐标系不匹配引发的点位偏移问题,截至2024年仍未在ggmap的原生功能中得到修复——核心矛盾是ggmap依赖的**Web墨卡托投影(EPSG:3857)与sf默认的WGS84地理坐标系(EPSG:4326)**不兼容,直接混用geom_sf和ggmap()会出现坐标映射错误,导致点位偏移。
下面是两种经过验证的有效规避方案:
方案1:转换sf数据至ggmap的投影坐标系
将sf对象转换为Web墨卡托投影后再叠加,可保证坐标完全匹配:
# 加载依赖包 library(ggplot2) library(ggmap) library(sf) # 加载城市sf数据 cities = sf::read_sf('{ "type": "FeatureCollection", "name": "cities", "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, "features": [{ "type": "Feature", "properties": { "city": "London" }, "geometry": { "type": "Point", "coordinates": [-0.13, 51.51] } }, { "type": "Feature", "properties": { "city": "Rome" }, "geometry": { "type": "Point", "coordinates": [12.48, 41.89] } }, { "type": "Feature", "properties": { "city": "Stockholm" }, "geometry": { "type": "Point", "coordinates": [18.07, 59.33] } }, { "type": "Feature", "properties": { "city": "Istanbul" }, "geometry": { "type": "Point", "coordinates": [28.96, 41.01] } } ] } ') # 转换sf数据到Web墨卡托投影(EPSG:3857) cities_3857 <- st_transform(cities, crs = 3857) # 加载底图并绘制 bb = c(left = -11, bottom = 35, right = 42, top = 65) europe = ggmap::get_stamenmap(bbox = bb, maptype = 'toner-lite', zoom = 3) ggmap(europe) + geom_sf(data = cities_3857, inherit.aes = FALSE, col = 'red', size = 3)
方案2:提取sf坐标用geom_point绘制
如果不想处理投影转换,可直接从sf对象中提取经纬度,用geom_point替代geom_sf,ggmap会自动适配坐标映射:
# 从sf对象中提取经纬度到普通数据框 cities_df <- cities %>% mutate( lon = st_coordinates(.)[, 1], lat = st_coordinates(.)[, 2] ) # 加载底图并叠加点位 bb = c(left = -11, bottom = 35, right = 42, top = 65) europe = ggmap::get_stamenmap(bbox = bb, maptype = 'toner-lite', zoom = 3) ggmap(europe) + geom_point(data = cities_df, aes(x = lon, y = lat), col = 'red', size = 3)
补充说明
偏移的本质是:ggmap获取的底图是Web墨卡托投影的栅格图,而sf默认的WGS84是地理坐标系(经纬度),直接用geom_sf叠加时,ggplot2不会自动将地理坐标转换为底图的投影坐标,导致点位被错误放置。
内容的提问来源于stack exchange,提问作者geotheory
相关产品推荐
相关产品推荐

