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

如何在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()

补充说明

  1. 如果原始地理数据不是sf格式,也可以用maps包的world数据转换后处理,核心逻辑都是保留完整地理范围+左连接GDP数据。
  2. 确保国家名称匹配:如果原始数据的region列和世界地图的国家名称列(如name_long)不匹配,需要先统一名称,否则连接会失败,导致更多区域显示为灰色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:40:56