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

R ggplot县级分级统计图:州界区分及无数据区县描边实现问题

R语言绘制美国县级分级统计图的问题修复方案

待解决问题

绘制美国县级宽带覆盖率分级统计图时遇到两个问题:

  • 州界与区县边界描边样式无差异,无法直观区分不同州范围
  • 无数据的区县无任何样式显示,图面存在大量空白

原有参考代码

初始实现代码

library(tidyverse)
library(urbnmapr)
library(urbnthemes)
library(janitor)

set_urbn_defaults(style = "map")

broadband <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-05-11/broadband.csv') %>% 
  clean_names()

broadband <- broadband %>% 
  right_join(counties, by = "county_name")

broadband %>% 
  drop_na(broadband_availability_per_fcc) %>%
  mutate(broadband_availability_per_fcc = case_when(
      broadband_availability_per_fcc == "-" ~ "0.00",
      TRUE ~ broadband_availability_per_fcc
    ),
    broadband_availability_per_fcc = as.double(broadband_availability_per_fcc)) %>% 
  ggplot(aes(long, lat, group = group, fill = broadband_availability_per_fcc)) +
    geom_polygon(color = "#ffffff", size = .25) +
    coord_map(projection = "albers", lat0 = 39, lat1 = 45)

后续尝试代码

states_sf <- get_urbn_map(map = "states", sf = TRUE)
counties_sf <- get_urbn_map(map = "counties", sf = TRUE)

broadband

broadband_map <- broadband %>% 
  inner_join(counties_sf, by = "county_name")

# 不添加县级geom_sf数据时运行正常
broadband_map %>% 
  drop_na(broadband_availability_per_fcc) %>% 
  mutate(broadband_availability_per_fcc = case_when(
    broadband_availability_per_fcc == "-" ~ "0.00",
    TRUE ~ broadband_availability_per_fcc),
  broadband_availability_per_fcc = as.double(broadband_availability_per_fcc)) %>% 
  ggplot() +
    geom_sf(data = states_sf, fill = NA, color = "black", size = 0.25) +
    # geom_sf(mapping = aes(fill = broadband_availability_per_fcc), color = NA) +
    coord_sf(datum = NA)

# 添加县级数据后无法得到预期效果
broadband_map %>% 
  drop_na(broadband_availability_per_fcc) %>% 
  mutate(broadband_availability_per_fcc = case_when(
    broadband_availability_per_fcc == "-" ~ "0.00",
    TRUE ~ broadband_availability_per_fcc
    ),
    broadband_availability_per_fcc = as.double(broadband_availability_per_fcc)) %>% 
  ggplot() +
    geom_sf(mapping = aes(fill = broadband_availability_per_fcc), color = NA) +
    geom_sf(data = states_sf, fill = NA, color = "black", size = 0.25) +
    coord_sf(datum = NA)

修复方案

通过调整图层绘制顺序、保留全量空间数据即可解决两个问题,修正后代码如下:

library(tidyverse)
library(urbnmapr)
library(urbnthemes)
library(janitor)
library(sf)

set_urbn_defaults(style = "map")

# 读取基础数据
broadband <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-05-11/broadband.csv') %>% 
  clean_names()
# 读取空间数据
states_sf <- get_urbn_map(map = "states", sf = TRUE)
counties_sf <- get_urbn_map(map = "counties", sf = TRUE)

# 关联属性数据和区县空间数据,保留所有区县
broadband_map <- counties_sf %>% 
  left_join(broadband, by = "county_name") %>% 
  # 先处理覆盖率字段,不要提前删缺失值
  mutate(broadband_availability_per_fcc = case_when(
    broadband_availability_per_fcc == "-" ~ "0.00",
    TRUE ~ broadband_availability_per_fcc
  ),
  broadband_availability_per_fcc = as.double(broadband_availability_per_fcc))

# 绘图
ggplot() +
  # 第一层:所有区县加浅色描边,解决无数据区县空白问题
  geom_sf(data = counties_sf, fill = NA, color = "#f0f0f0", size = 0.1) +
  # 第二层:有数据的区县按值填充,不需要额外描边
  geom_sf(data = broadband_map, aes(fill = broadband_availability_per_fcc), color = NA) +
  # 第三层:州界用深颜色+更粗的描边,解决州界和区县边界区分问题
  geom_sf(data = states_sf, fill = NA, color = "#212121", size = 0.4) +
  # 调整投影
  coord_sf(projection = "albers", lat0 = 39, lat1 = 45, datum = NA)

修复说明

  1. 分层绘制解决边界区分问题:区县描边用浅灰色细线条,州界用深灰色粗线条,层级差异明显
  2. 先绘制全量区县底层描边,无数据的区县也会显示浅灰色轮廓,不会出现空白
  3. 关联空间数据时用left_join保留所有区县的几何信息,避免提前过滤导致数据缺失

内容的提问来源于stack exchange,提问作者Indescribled

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:39:03