如何在ggplot2地图中为无数据区域设置灰色填充
问题描述
使用ggplot2、ggmap、ggthemes绘制人均GDP地图时,尝试通过scale_fill_viridis_b()设置na.value="grey"来让无数据区域显示灰色,但该设置未生效。
当前使用的代码:
ggplot(GDP_XXI_average_coor,aes(long,lat,group=group))+ geom_polygon(aes(fill=Average_GDP),colour="white")+ scale_fill_viridis_b(breaks=c(0, 1000, 2000, 5000, 10000, 20000, 50000), na.value="grey")+ labs(fill="GDP per \ncapita ", title="GDP per capita in 21st century", na.value= "No data") + theme_map()
加载的包:
library(ggplot2) library(ggmap) library(ggthemes)
数据集前20行结构:
structure(list(long = c(-69.8991241455078, -69.8957061767578, -69.9421920776367, -70.004150390625, -70.0661163330078, -70.0508804321289, -70.0351104736328, -69.97314453125, -69.9118118286133, -69.8991241455078, 74.8913116455078, 74.8402328491211, 74.7673797607422, 74.7389602661133, 74.7266616821289, 74.6689453125, 74.5589904785156, 74.3721694946289, 74.3761672973633, 74.4979553222656), lat = c(12.4520015716553, 12.4229984283447, 12.4385251998901, 12.50048828125, 12.5469722747803, 12.5970697402954, 12.6141109466553, 12.567626953125, 12.48046875, 12.4520015716553, 37.2316398620605, 37.2250518798828, 37.2491722106934, 37.28564453125, 37.2907218933105, 37.2667007446289, 37.2366218566895, 37.15771484375, 37.1373519897461, 37.0572242736816), group = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), order = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L), region = c("Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Aruba", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan" ), subregion = c(NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_), Average_GDP = c(28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 28473.0717233333, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316, 471.741233426316)), row.names = c(NA, 20L), class = "data.frame")
解决方案
问题根源
从提供的数据集片段可以看到,所有行的Average_GDP都有有效值,没有NA值。na.value仅对数据中存在NA的区域生效,而如果无数据的国家/区域根本没有出现在数据框中,ggplot2不会绘制这些区域,自然也不会应用na.value设置。
解决步骤
需要先获取完整的世界地理数据,再与GDP数据做左连接,保留所有地理区域,这样无GDP数据的区域会自动生成NA值,之后na.value="grey"就能生效。
具体实现代码:
# 加载必要包 library(ggplot2) library(ggthemes) library(dplyr) library(rnaturalearth) library(rnaturalearthdata) # 获取完整世界地图矢量数据(sf格式,更适合空间绘图) world_map <- ne_countries(scale = "medium", returnclass = "sf") # 从原始数据中提取唯一的国家-人均GDP对应关系 gdp_clean <- GDP_XXI_average_coor %>% group_by(region) %>% summarise(Average_GDP = first(Average_GDP)) %>% # 重命名列,确保和世界地图数据的国家名称列匹配 rename(name_long = region) # 左连接:保留所有国家,无GDP数据的国家Average_GDP会设为NA world_with_gdp <- left_join(world_map, gdp_clean, by = "name_long") # 绘制地图 ggplot(world_with_gdp) + geom_sf(aes(fill = Average_GDP), colour = "white") + scale_fill_viridis_b(breaks = c(0, 1000, 2000, 5000, 10000, 20000, 50000), na.value = "grey") + labs(fill = "人均GDP", title = "21世纪人均GDP分布", caption = "无数据区域显示为灰色") + theme_map()
补充说明
- 如果原始地理数据不是sf格式,也可以用
maps包的world数据转换后处理,核心逻辑都是保留完整地理范围+左连接GDP数据。 - 确保国家名称匹配:如果原始数据的
region列和世界地图的国家名称列(如name_long)不匹配,需要先统一名称,否则连接会失败,导致更多区域显示为灰色。
内容的提问来源于stack exchange,提问作者Ayaz Aliyev
相关产品推荐
相关产品推荐

