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)
修复说明
- 分层绘制解决边界区分问题:区县描边用浅灰色细线条,州界用深灰色粗线条,层级差异明显
- 先绘制全量区县底层描边,无数据的区县也会显示浅灰色轮廓,不会出现空白
- 关联空间数据时用left_join保留所有区县的几何信息,避免提前过滤导致数据缺失
内容的提问来源于stack exchange,提问作者Indescribled
相关产品推荐
相关产品推荐

