You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言中基于sf绘制带比例符号的地区叠加地图问题求助

问题描述

我通过sf包导入了一个包含某拉美国家1874个地区的GeoDataFrame,数据结构如下:

Classes ‘sf’ and 'data.frame':  1874 obs. of  8 variables:
$ NOMBDIST: chr  "CODO DEL POZUZO" "TOURNAVISTA" "ALEXANDER VON HUMBOLDT" "IRAZOLA" ...
$ POBTOTAL: num  7768 6219 6085 10941 9003 ...
$ UBIGEO  : num  100902 100904 250305 250302 250304 ...
$ MC_PR   : num  41 41.4 46 43.8 35.3 ...
$ C_PR    : num  9.23 5.22 3.27 2.64 2.21 ...
$ TT      : num  1084 556 1530 2769 1535 ...
$ IDH     : num  0.324 0.409 0.423 0.378 0.437 ...
$ geom    :sfc_MULTIPOLYGON of length 1874; first list element: List of 1
..$ :List of 1
.. ..$ : num [1:1294, 1:2] -75.3 -75.3 -75.3 -75.3 -75.3 ...
..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
- attr(*, "sf_column")= chr "geom"
- attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA
..- attr(*, "names")= chr [1:7] "NOMBDIST" "POBTOTAL" "UBIGEO" "MC_PR" ...

字段说明:

  • NOMBDIST:地区名称
  • POBTOTAL:地区总人口
  • UBIGEO:地区编码
  • MC_PR:科研岗位女性占比
  • C_PR:科研岗位从业者占比
  • TT:总劳动者数
  • IDH:人类发展指数

我想要制作一张地图:以灰色地区为背景,在每个地区的中心点绘制点,点的大小由TT字段决定,颜色随MC_PR字段渐变。尝试了以下代码,但结果不符合预期:

ggplot() +
geom_sf(data = gdf, fill = "grey95") +
geom_sf(data = centroides, pch = 21,
aes(size = TT, fill = MC_PR),
col = "grey20") +
xlim(c(2200000, 7150000)) +
ylim(c(1380000, 5500000)) +
scale_size(range = c(1, 9), guide = guide_legend(
direction = "horizontal",
nrow = 1,
label.position = "bottom")) +
scale_fill_gradientn(colours = hcl.colors(5, "RdBu", rev = TRUE,alpha = 0.9)) +
guides(fill = guide_legend(title = "")) +
theme_void() +
theme(legend.position = "bottom")
解决方案

从代码和预期效果来看,问题集中在中心点数据处理和图例配置上,以下是修正步骤:

1. 正确生成地区中心点

确保centroides是从原始GeoDataFrame正确计算得到的中心点,且保留所需字段:

# 计算每个地区的中心点(优先取最大面的中心,适配多边形地区)
centroides <- st_centroid(gdf, of_largest_polygon = TRUE)
# 保留绘图需要的字段
centroides <- centroides %>% select(NOMBDIST, TT, MC_PR, geom)

若原始数据是经纬度坐标系(如EPSG:4326),直接使用st_centroid即可;若是投影坐标系也能正常计算。

2. 修正颜色渐变的图例配置

MC_PR是连续数值,不能用离散的guide_legend,需改用guide_colourbar显示渐变条:

scale_fill_gradientn(
  colours = hcl.colors(5, "RdBu", rev = TRUE, alpha = 0.9),
  name = "科研岗位女性占比(%)" # 自定义颜色图例标题
) +
guides(
  size = guide_legend(
    direction = "horizontal",
    nrow = 1,
    label.position = "bottom",
    title = "总劳动者数" # 自定义大小图例标题
  ),
  fill = guide_colourbar(
    direction = "horizontal",
    barwidth = 15,
    barheight = 1,
    title.position = "top"
  )
)

3. 优化地图范围裁剪方式

用xlim/ylim容易裁剪掉地理要素,建议先通过st_crop裁剪原始数据:

# 定义裁剪范围(需匹配原始数据的坐标系)
bbox <- st_bbox(c(xmin = 2200000, ymin = 1380000, xmax = 7150000, ymax = 5500000), crs = st_crs(gdf))
gdf_cropped <- st_crop(gdf, bbox)
centroides_cropped <- st_crop(centroides, bbox)

# 最终绘图代码
ggplot() +
  geom_sf(data = gdf_cropped, fill = "grey95", color = "white", size = 0.1) + # 添加细边框区分地区
  geom_sf(data = centroides_cropped, pch = 21, aes(size = TT, fill = MC_PR), color = "grey20") +
  scale_size(range = c(1, 9), guide = guide_legend(
    direction = "horizontal",
    nrow = 1,
    label.position = "bottom",
    title = "总劳动者数"
  )) +
  scale_fill_gradientn(
    colours = hcl.colors(5, "RdBu", rev = TRUE, alpha = 0.9),
    name = "科研岗位女性占比(%)"
  ) +
  guides(
    fill = guide_colourbar(
      direction = "horizontal",
      barwidth = 15,
      barheight = 1,
      title.position = "top"
    )
  ) +
  theme_void() +
  theme(
    legend.position = "bottom",
    legend.box = "vertical",
    legend.margin = margin(10, 10, 10, 10)
  )

4. 额外优化建议

  • 给背景地区添加细白色边框,能更清晰区分不同区域;
  • 若点重叠严重,可添加alpha = 0.8参数降低点的透明度;
  • 调整scale_size的range参数,可控制点的大小区间。

内容的提问来源于stack exchange,提问作者José Carlos Rojas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:00:39