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

如何在geom_sf中为AREA>0.1的值用Spectral色板,同时展示其他值与NA

问题描述

我希望实现以下地图样式需求:

  • AREA大于0.1的空间要素使用RColorBrewer包中的Spectral调色板
  • AREA小于0.1的要素设置为深灰色(或填充图案效果)
  • NA值渲染为浅灰色
  • 确保地图上所有要素都有对应样式

我尝试了两种方法但都没达到预期效果,代码如下:

library(ggnewscale)
library(tidyverse)
library(sf)

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), 
                  quiet = TRUE)

# 添加NA值
nc$AREA[c(1,2,3)] <- NA

# 第一种尝试
ggplot(nc) +
  geom_sf(aes(fill = AREA > 0.1)) +
  new_scale_fill() +
  geom_sf(aes(fill = AREA))+
  scale_fill_gradientn(colors = RColorBrewer::brewer.pal(9, "Spectral"),
                       na.value = "grey90")
# 第二种尝试
remove_col <- "AREA"
remove_val <- 0.1

nc %>%
  filter(.data[[remove_col]] < remove_val) %>%
  ggplot() +
  geom_sf(aes(fill = AREA)) +
  new_scale_fill() +
  geom_sf(aes(fill = .data[[remove_col]]), color = "black") +
  scale_fill_gradientn(colors = RColorBrewer::brewer.pal(9, "Spectral"),
                       na.value = "grey90")
解决方案

可以通过分层绘制要素的方式精准控制不同类别要素的样式,先绘制低数值和NA要素,再绘制目标数值区间的要素并应用调色板,具体实现如下:

方法1:深灰色填充(基础版)

library(ggnewscale)
library(tidyverse)
library(sf)
library(RColorBrewer)

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
nc$AREA[c(1,2,3)] <- NA

ggplot() +
  # 绘制AREA≤0.1的要素,填充深灰色
  geom_sf(data = nc %>% filter(AREA <= 0.1 & !is.na(AREA)), 
          fill = "grey30", color = "white") +
  # 绘制NA值要素,填充浅灰色
  geom_sf(data = nc %>% filter(is.na(AREA)), 
          fill = "grey90", color = "white") +
  # 开启新的填充比例尺,避免和前面的固定颜色冲突
  new_scale_fill() +
  # 绘制AREA>0.1的要素,应用Spectral调色板
  geom_sf(data = nc %>% filter(AREA > 0.1), 
          aes(fill = AREA), color = "white") +
  scale_fill_gradientn(colors = brewer.pal(9, "Spectral")) +
  labs(fill = "AREA (>0.1)") +
  theme_minimal()

方法2:填充图案(增强区分度)

如果需要用填充图案替代深灰色,提升视觉区分度,可以使用ggpattern包实现:

library(ggpattern)

ggplot() +
  # AREA≤0.1的要素用斜线图案+深灰色填充
  geom_sf_pattern(data = nc %>% filter(AREA <= 0.1 & !is.na(AREA)),
                  fill = "grey30",
                  pattern = "stripe",
                  pattern_color = "white",
                  pattern_fill = "white",
                  pattern_density = 0.1,
                  color = "white") +
  # NA值要素填充浅灰色
  geom_sf(data = nc %>% filter(is.na(AREA)), 
          fill = "grey90", color = "white") +
  new_scale_fill() +
  # AREA>0.1的要素应用Spectral调色板
  geom_sf(data = nc %>% filter(AREA > 0.1), 
          aes(fill = AREA), color = "white") +
  scale_fill_gradientn(colors = brewer.pal(9, "Spectral")) +
  labs(fill = "AREA (>0.1)") +
  theme_minimal()

原方法问题说明

  • 第一种尝试:两个geom_sf图层叠加时,后绘制的图层会覆盖前一个,且fill = AREA > 0.1是逻辑值,和后续数值型fill的比例尺冲突,导致样式混乱。
  • 第二种尝试:使用filter过滤了数据,导致AREA>0.1的要素未被绘制,无法展示完整地图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:07:50