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

如何基于两列数据为美国各州分区域实现自定义渐变填充?

问题描述

需要为美国各州的县级地图分区域上色:以州质心为界,州质心上方的县基于Qt列数值使用绿色系配色,州质心下方的县基于Apo列数值使用蓝色系配色。现有代码仅显示蓝色系,无法实现分区域的双色系需求。

解决方案

方案1:使用ggnewscale实现独立填充比例尺

该方案让Apo和Qt两个变量各自使用独立的颜色映射,无需缩放数值,逻辑更清晰:

步骤1:安装并加载依赖包

install.packages("ggnewscale") # 未安装时执行
library(tidyverse)
library(usmap)
library(RColorBrewer)
library(ggnewscale)

步骤2:整理数据(简化原处理逻辑)

# 原始数据集
read.table(text = "State     Apo    Qt
NJ  1     10
MO  2     20
SD  3     30
NY  4     40
FL  5     50
OK  6     60
NE  7     70
KY  8     80
ME  9     90
CA  10  100
NC  11  110
MA  12  120
CT  13  140", header = T, stringsAsFactor = F) -> ex1

# 转换为长格式,保留州名、变量类型和对应数值
ex1 %>% 
  pivot_longer(-State, names_to = "var", values_to = "val") -> ex_long

# 获取县级地图数据,标记每个县对应的变量类型(Apo/Qt)
usc <- usmap::us_map(regions = "counties")
us_state <- usmap::us_map()

usc %>% 
  group_by(full, county) %>% 
  mutate(county_y_center = mean(range(y))) %>% 
  group_by(full) %>% 
  mutate(state_y_center = mean(range(y))) %>% 
  # 根据质心位置标记变量类型
  mutate(var = ifelse(state_y_center > county_y_center, "Apo", "Qt")) %>% 
  # 关联原始数据集的数值
  left_join(ex_long, by = c("abbr" = "State", "var" = "var")) -> usc_data

步骤3:分区域绘图

# 定义配色:Qt用绿色系,Apo用蓝色系
qt_palette <- colorRampPalette(brewer.pal(3, "Greens"))(10)
apo_palette <- colorRampPalette(brewer.pal(3, "Blues"))(10)

ggplot() +
  # 绘制Qt区域(质心上方的县)
  geom_polygon(data = usc_data %>% filter(var == "Qt"),
               aes(x = x, y = y, group = group, fill = val),
               color = NA) +
  # 设置Qt的颜色比例尺
  scale_fill_gradientn(name = "Qt 值", colors = qt_palette,
                       guide = guide_colorbar(barwidth = 0.8, barheight = 18)) +
  # 启用新的填充比例尺,用于Apo区域
  new_scale_fill() +
  # 绘制Apo区域(质心下方的县)
  geom_polygon(data = usc_data %>% filter(var == "Apo"),
               aes(x = x, y = y, group = group, fill = val),
               color = NA) +
  # 设置Apo的颜色比例尺
  scale_fill_gradientn(name = "Apo 值", colors = apo_palette,
                       guide = guide_colorbar(barwidth = 0.8, barheight = 18)) +
  # 添加州边界
  geom_polygon(data = us_state, aes(x = x, y = y, group = group),
               fill = NA, color = "black") +
  theme_void() +
  theme(legend.position = "right")

方案2:修正原代码逻辑(无需额外包)

如果不想引入新包,可调整数值缩放和比例尺设置,解决原代码的颜色覆盖问题:

# 原数据处理部分保持不变,直接修改绘图代码
mcolor <- c(colorRampPalette(brewer.pal(3, "Greens"))(3), 
            colorRampPalette(brewer.pal(3, "Blues"))(3))

ggplot() + 
  geom_polygon(data = usc_map_ex %>% filter(is.na(Apo)),
               aes(x,y, group = group, fill = Qt, color = "")) +
  # 调整Apo的缩放倍数,让数值范围与Qt不重叠
  geom_polygon(data = usc_map_ex %>% filter(is.na(Qt)),
               aes(x,y, group = group, fill = Apo * 5, color = "")) +
  geom_polygon(data = us, aes(x,y, group = group), fill = NA, color = "black") +
  scale_colour_manual(values = 'transparent', guide = "none") +
  scale_fill_gradientn(
    name = "数值",
    breaks = c(10, 70, 140, 5, 25, 65),
    labels = c("Qt:10", "Qt:70", "Qt:140", "Apo:1", "Apo:5", "Apo:13"),
    # 对应颜色的位置:前3个绿色映射Qt范围,后3个蓝色映射Apo范围
    values = c(0, 0.5, 1, 0, 0.5, 1) / 1,
    limits = c(0, 140),
    colors = mcolor,
    guide = guide_colorbar(barwidth = 0.8, barheight = 18)
  ) +
  theme_void()

方案对比

  • 方案1:逻辑清晰,两个变量独立配色,支持分开显示图例,适合需要明确区分两类数值的场景
  • 方案2:无需额外依赖包,但需手动调整数值缩放,图例合并为一个,适合只需要统一视觉呈现的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:15:43