R语言ggplot2绘制德国NUTS2地图时如何添加差异化区域边界
R ggplot2绘制东西德NUTS2地图 实现两区域公共边界加粗效果
现有基础实现
在R环境中使用ggplot2包开展地理可视化工作,基于NUTS2层级地理数据绘制德国地图时,已完成基础地图代码编写,运行生成的地图中西德、东德区域分别以绿色、蓝色填充,需要为两个区域设置差异化样式的公共边界,通过加粗线宽、修改线条颜色等方式实现区分,最终达成两区域间边界线加粗的显示效果。
现有实现代码如下:
# 数据来源:历史GIS数据集 germany_shapes_1990 <- st_read("Federal Republic of Germany 1990-2009/Germany_1990_91_v.1.0.shp", layer="Germany_1990_91_v.1.0") # 读取现行NUTS行政区划数据 nuts_shapes <- st_read("NUTS_RG_20M_2016_4326.shp", layer="NUTS_RG_20M_2016_4326") # 坐标系转换,匹配1990年德国地图坐标系 nuts_shapes_germ <- st_transform(nuts_shapes, st_crs(germany_shapes_1990)) # 仅保留NUTS2层级数据 nuts_shapes_germ<- filter(nuts_shapes_germ, LEVL_CODE == 2) # 仅保留德国境内区域 nuts_shapes_germ <- nuts_shapes_germ %>% filter(grepl('DE', NUTS_ID)) #################### # 1990年绘图部分 # #################### # 1990年地图数据清洗 germ_shapes_1990 <- germ_clean_1990 %>% # 匹配东西德归属标签 # 注:归属数据来自预处理脚本生成的regress_dat表 east_west <- regress_dat %>% select(user_loc,user_country_1990) %>% distinct(user_loc, .keep_all=TRUE) ew_germ_shapes <- nuts_shapes_germ %>% left_join(east_west, by=c(NUTS_ID = "user_loc")) %>% drop_na(user_country_1990) # 重命名区域标签 ew_germ_shapes$user_country_1990[ew_germ_shapes$user_country_1990 == "DE"] <- "West Germany" ew_germ_shapes$user_country_1990[ew_germ_shapes$user_country_1990 == "GC"] <- "East Germany" regions <- ew_germ_shapes$user_country_1990 palette <- distinctColorPalette(length(regions)) # 绘制德国基础填色地图 basic_germ_map <- ew_germ_shapes %>% ggplot() + geom_sf(aes(fill=regions)) + scale_fill_manual(values=palette) + ggtitle("1990 Germany in Modern NUTS2") + theme(legend.key.size = unit(2,'cm'), legend.text = element_text(size=10)) basic_germ_map
现有代码运行效果如下:
实现东西德边界加粗的方案
要单独加粗东西德的公共边界,不需要修改底层NUTS2的细碎边界,只需要先按东西德属性做区域融合,再单独叠加一层边界线即可,操作逻辑是先按东西德分组融合几何要素,把同属东德/西德的NUTS2多边形合并成两个整体多边形,保留原有基础填色层并设置细的内部边界线宽,再新增一层geom_sf专门绘制融合后的东西德外边界,单独设置粗线宽、高对比颜色,放在填色层上方。
修改后的核心绘图代码如下:
library(sf) library(dplyr) library(ggplot2) library(ggpubr) # 先做东西德区域融合,合并同区域的NUTS2多边形 ew_boundary <- ew_germ_shapes %>% group_by(user_country_1990) %>% summarise(geometry = st_union(geometry)) # 绘制带加粗公共边界的地图 final_germ_map <- ew_germ_shapes %>% ggplot() + # 底层NUTS2填色层,设置细的内部边界 geom_sf(aes(fill=user_country_1990), linewidth = 0.2, color = "white") + # 手动指定东西德填充色,匹配绿/蓝填充效果 scale_fill_manual(values = c("East Germany" = "#4575B4", "West Germany" = "#91CF60"), name = "区域归属") + # 叠加东西德大区边界,设置加粗线宽和醒目颜色 geom_sf(data = ew_boundary, aes(color = user_country_1990), fill = NA, linewidth = 1.2) + # 边界线颜色统一设置为高对比红色,公共边界会自动按两个大区的邻接边绘制加粗效果 scale_color_manual(values = c("East Germany" = "#D73027", "West Germany" = "#D73027"), guide = "none") + ggtitle("1990年德国东西德分区图(基于现代NUTS2区划)") + theme(legend.key.size = unit(2,'cm'), legend.text = element_text(size=10)) final_germ_map
关键参数说明
- 底层
geom_sf的linewidth = 0.2+color = "white":用来绘制NUTS2单元之间的细白色分割线,区分下辖区划 - 融合后的
ew_boundary层设置fill = NA:保证不会覆盖下层的填色效果,只绘制边界线 - 两层
geom_sf的绘制顺序:填色层在下,边界层在上,保证粗边界不会被下层元素遮盖 - 不需要公共边界特殊颜色时,可以把边界色改成黑色,线宽调整到1-1.5之间就能达到清晰的加粗区分效果
注意:如果运行时出现拓扑错误,可以在融合几何前加一步
st_make_valid()修正几何,即把融合代码改成summarise(geometry = st_union(st_make_valid(geometry)))即可。
内容的提问来源于stack exchange,提问作者beaner0228
相关产品推荐
相关产品推荐

