在R语言ggplot2中实现地图叠加条形图(替代已弃用的ggsubplot)
ggplot2地图叠加条形图实现方案
方案1:基于sf矩形生成(兼容性最优,适合单系列条形)
该方案不需要额外安装冷门依赖,基于你提供的示例代码调整即可,核心逻辑是为每个点位生成对应高度的条形矩形sf对象,直接叠加到地图上。
修正后的可运行代码
# devtools::install_github("hrbrmstr/albersusa") library(albersusa) library(sf) library(ggplot2) library(dplyr) # 生成底图 statesus <- usa_sf("laea") p <- ggplot() + geom_sf(data = statesus, size = 0.4) # 点位数据(已修正原代码经纬度参数倒置的问题) lon <- c(-68.24, -109.88, -80.88, -113.85) lat <- c(44.35, 38.24, 25.37, 48.75) park <- c("Acadia", "Canyonlands", "Everglades", "Glacier") proportion <- c(0.10, 0.80, 0.05, 0.45) # 条形高度比例 parkdat <- data.frame(lon = lon, lat = lat, park = park, proportion = proportion) # 转sf并适配底图的LAEA投影 parkdatsf <- st_as_sf(parkdat, coords = c("lon", "lat"), crs = 4326, agr = "constant") %>% st_transform(crs = st_crs(statesus)) # 提取点位投影后的坐标值 park_coords <- st_coordinates(parkdatsf) parkdatsf <- parkdatsf %>% mutate(x = park_coords[,1], y = park_coords[,2]) # 生成每个点位对应的条形矩形(可自定义条形宽度、高度缩放系数) bar_width <- 80000 # 条形宽度80km,适配底图米级单位 bar_height_scale <- 300000 # 比例1对应300km高度,可自行调整 bar_sf <- parkdatsf %>% rowwise() %>% mutate(geometry = st_sfc(st_polygon(list( rbind( c(x - bar_width/2, y), c(x + bar_width/2, y), c(x + bar_width/2, y + proportion*bar_height_scale), c(x - bar_width/2, y + proportion*bar_height_scale), c(x - bar_width/2, y) ) )))) %>% st_set_crs(st_crs(statesus)) # 叠加条形到地图上 p + geom_sf(data = bar_sf, fill = "steelblue", alpha = 0.8, color = "black") + # 可选添加点位名称标注 geom_sf_text(data = parkdatsf, aes(label = park), nudge_y = 30000, size = 3)
方案2:多系列分组条形实现
如果需要在单个点位放置多分类的分组条形图,可以结合annotation_custom()将迷你ggplot条形图逐个放置到对应坐标位置,逻辑如下:
- 对每个点位的分类数据生成独立的迷你条形图,去除所有坐标轴、背景等非必要主题元素
- 通过
annotation_custom()将迷你图批量绑定到地图的对应坐标上
内容的提问来源于stack exchange,提问作者BonnieM
相关产品推荐
相关产品推荐

