如何让经纬度坐标与美国州界地图处于同一坐标系?
问题描述
我有如下经纬度坐标数据:
library(tidyverse) library(haven) library(tidycensus) library(tigris) coords <- data.frame(lat = c(38.09720, 36.85298, 31.31517, 21.48344), long = c(-121.38785, -75.97742, -85.85522, -158.03648))
随后获取了美国州界地图数据:
geo <- get_acs(geography = "state", variables = c(x = "B04006_036"), year = 2021, geometry = TRUE, keep_geo_vars=TRUE) %>% filter(STATEFP!="72") # 将阿拉斯加和夏威夷移到地图主区域旁 geo <- shift_geometry(geo)
尝试将坐标叠加到州界地图绘制:
ggplot(data = coords) + geom_point(aes(x=lat, y=long)) + geom_sf(fill = "transparent", color = "gray50", size = 1, data = geo %>% group_by(STATEFP) %>% summarise()) + theme(panel.background = element_rect(fill = 'white')) + theme(panel.grid = element_blank(),axis.title = element_blank(), axis.text = element_blank(),axis.ticks = element_blank(), panel.border = element_blank())
绘制结果显示所有坐标点集中在同一位置,不符合预期,请问如何修改让地图与坐标处于同一比例尺?
问题原因与修正方案
核心问题
两个关键错误导致点位置异常:
- 轴映射颠倒:
geom_point中把纬度(lat)设为x轴、经度(long)设为y轴,但地图坐标系是x对应经度、y对应纬度,轴对应关系完全相反。 - 坐标系不匹配:
shift_geometry()返回的地图采用Albers等面积投影(EPSG:5070),而原始坐标是WGS84经纬度(EPSG:4326),未转换坐标直接叠加会导致位置偏差。
修正方案
方法一:用geom_sf()绘制点(推荐)
将坐标转换为sf对象,统一坐标系后直接用geom_sf()绘制,自动匹配地图投影:
# 将坐标转换为sf对象,指定原始坐标系为WGS84 coords_sf <- st_as_sf(coords, coords = c("long", "lat"), crs = 4326) %>% # 转换为和geo相同的投影坐标系 st_transform(crs = st_crs(geo)) # 绘图:先画地图,再添加坐标点 ggplot() + geom_sf(data = geo %>% group_by(STATEFP) %>% summarise(), fill = "transparent", color = "gray50", size = 1) + geom_sf(data = coords_sf, color = "red", size = 3) + # 用红色突出显示点 theme(panel.background = element_rect(fill = 'white'), panel.grid = element_blank(), axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), panel.border = element_blank())
方法二:修正轴映射并转换坐标
如果坚持使用geom_point,需先转换坐标到地图投影,再正确映射x/y轴:
# 转换坐标并提取平面坐标的x/y值 coords_proj <- st_as_sf(coords, coords = c("long", "lat"), crs = 4326) %>% st_transform(crs = st_crs(geo)) %>% mutate(x = st_coordinates(.)[,1], y = st_coordinates(.)[,2]) %>% st_drop_geometry() # 绘图:使用转换后的x/y坐标映射 ggplot() + geom_sf(data = geo %>% group_by(STATEFP) %>% summarise(), fill = "transparent", color = "gray50", size = 1) + geom_point(data = coords_proj, aes(x = x, y = y), color = "red", size = 3) + theme(panel.background = element_rect(fill = 'white'), panel.grid = element_blank(), axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), panel.border = element_blank())
效果说明
修正后,四个坐标点会正确对应到:加州(38.09720, -121.38785)、弗吉尼亚州(36.85298, -75.97742)、阿拉巴马州(31.31517, -85.85522)、夏威夷(21.48344, -158.03648),与州界地图完全匹配。
内容的提问来源于stack exchange,提问作者bill999
相关产品推荐
相关产品推荐

