如何在ggplot2中实现点图层叠加到多边形图层的空间可视化?
问题原因分析
- 数据集映射逻辑错误:你传入
ggplot()的主数据集grid_data是科罗拉多城市点数据,仅包含21条记录,但是aes(fill = incp_prj$Poverty_Me)调用的是普查片区数据集的字段,行数远大于21,长度不匹配触发报错 - 图层类型适配错误:普查片区是矢量多边形数据,
geom_tile是用来绘制栅格/规则网格的,不能用来渲染不规则的普查片区边界 - 坐标对齐逻辑缺失:你虽然给城市点设置了和shapefile一致的投影对象,但直接提取
long/lat是原始WGS84地理坐标,没有做实际的坐标转换,叠加后会出现位置偏移
修正后的可运行代码
推荐使用适配性更强的sf包方案,和ggplot2兼容性更高:
# 加载依赖包 library(ggplot2) library(maps) library(sf) library(dplyr) # 读取收入普查片区shp,转sf格式 incp_sf <- st_read("Income_Poverty_(Census_Tracts).shp") # 统一转成WGS84投影方便和城市经纬度匹配 incp_sf <- st_transform(incp_sf, crs = 4326) # 提取科罗拉多城市点 data(us.cities) co_cities <- us.cities %>% filter(country.etc == "CO") # 转sf格式对齐投影 co_cities_sf <- st_as_sf(co_cities, coords = c("long", "lat"), crs = 4326) # 绘图 ggplot() + # 先画普查片区多边形,映射收入字段填充色 geom_sf(data = incp_sf, aes(fill = Poverty_Me)) + # 再叠加城市点 geom_sf(data = co_cities_sf, color = "red", size = 2) + # 可选配置:调整配色、标题等 scale_fill_viridis_c() + labs(title = "科罗拉多州普查片区家庭平均收入与城市分布", fill = "家庭平均收入") + theme_minimal()
如果需要兼容你原来的sp体系写法,代码如下:
library(ggplot2) library(maps) library(sp) library(raster) library(spdplyr) library(broom) incp_prj <- shapefile("Income_Poverty_(Census_Tracts).shp") # 转成ggplot可识别的多边形数据框 incp_df <- tidy(incp_prj, region = "OBJECTID") # 替换为你shp里的唯一标识字段名 # 关联收入属性数据 incp_df <- left_join(incp_df, incp_prj@data, by = c("id" = "OBJECTID")) # 处理科罗拉多城市点 data(us.cities) coords <- cbind(us.cities$long, us.cities$lat) us.cities <- SpatialPointsDataFrame(coords = coords, data = us.cities, proj4string = CRS("+proj=longlat +datum=WGS84")) # 投影转换对齐shp us.cities_prj <- spTransform(us.cities, crs(incp_prj)) co.cities <- us.cities_prj %>% filter(country.etc == "CO") co.cities_df <- as.data.frame(co.cities) # 绘图 ggplot() + geom_polygon(data = incp_df, aes(x = long, y = lat, group = group, fill = Poverty_Me), color = "white", linewidth = 0.1) + geom_point(data = co.cities_df, aes(x = long, y = lat), color = "red", size = 2) + coord_equal() + labs(fill = "家庭平均收入") + theme_minimal()
注意事项
- 如果你使用
sp体系的写法,需要把tidy()里的region参数和left_join的关联字段替换为你实际shp里的唯一主键字段名,一般是OBJECTID或者GEOID - 两种写法都默认保留了WGS84地理坐标,如果你需要用原shp的投影,只需要调整
st_transform的crs参数或者修改城市点的投影转换逻辑即可
内容的提问来源于stack exchange,提问作者Abby L
相关产品推荐
相关产品推荐

