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

如何在ggplot中用颜色混合表示北卡州地图的多颜色平局?

北卡州县域颜色可视化需求与解决方案

1. 单一颜色分配地图

先为每个县随机分配单一颜色并生成地图,代码如下:

library(sf)
library(dplyr)
library(ggplot2)

nc <- st_read(system.file("gpkg/nc.gpkg", package = "sf"), quiet = TRUE) %>%
  st_transform(st_crs(4326)) %>%
  st_cast("POLYGON")

set.seed(123)
colors <- c("red", "blue", "green", "yellow", "purple", "orange")
favorite_color <- sample(colors, nrow(nc), replace = TRUE)
my_df <- data.frame(NAME = nc$NAME, favorite_color)

nc_merged <- merge(nc, my_df, by = "NAME", all.x = TRUE)

ggplot(data = nc_merged) +
  geom_sf(aes(fill = favorite_color)) +
  scale_fill_manual(values = colors) +
  theme_minimal() +
  labs(title = "Favorite Color by County",
       fill = "Favorite Color")

北卡州单一颜色县地图

2. 平局县设为白色的地图

制作允许县拥有多种偏好颜色的地图,平局县设为白色,代码如下:

set.seed(123)
colors <- c("red", "blue", "green", "yellow", "purple", "orange")
favorite_color <- replicate(nrow(nc), {
    sample_size <- sample(1:3, 1)
    sample(colors, sample_size, replace = FALSE)
})

my_df <- data.frame(NAME = nc$NAME, favorite_color = sapply(favorite_color, function(x) paste(x, collapse = ", ")))

my_df$favorite_color[sapply(favorite_color, length) > 1] <- NA

nc_merged <- merge(nc, my_df, by = "NAME", all.x = TRUE)

ggplot(data = nc_merged) +
    geom_sf(aes(fill = favorite_color)) +
    scale_fill_manual(values = c(colors, "white"), na.value = "white") +
    theme_minimal() +
    labs(title = "Favorite Color by County (with Ties)",
         fill = "Favorite Color")

北卡州含平局的县地图(平局县为白色)

核心问题

对于存在颜色平局(如2种或3种颜色)的县,能否将这些颜色混合生成新颜色?即无平局的县使用单一颜色,平局县使用混合后的颜色?

尝试的ggpattern方案(效果不佳)

初次尝试

用ggpattern实现但可读性极差:

set.seed(123)
colors <- c("red", "blue", "green", "yellow", "purple", "orange")
favorite_color <- replicate(nrow(nc), {
    sample_size <- sample(1:3, 1)
    sample(colors, sample_size, replace = FALSE)
})

my_df <- data.frame(NAME = nc$NAME, 
                    favorite_color = sapply(favorite_color, function(x) paste(x, collapse = ", ")))

unique_patterns <- unique(my_df$favorite_color)
pattern_colors <- setNames(rainbow(length(unique_patterns)), unique_patterns)

nc_merged <- merge(nc, my_df, by = "NAME", all.x = TRUE)

ggplot(data = nc_merged) +
    geom_sf_pattern(aes(fill = favorite_color, pattern_fill = favorite_color),
                    pattern = "stripe", color = "black", size = 0.2) +
    scale_fill_manual(values = pattern_colors) +
    scale_pattern_fill_manual(values = pattern_colors) +
    theme_minimal() +
    labs(title = "Favorite Color by County (with Patterns for Ties)",
         fill = "Favorite Color")

使用ggpattern的平局县地图

改进后尝试

调整后效果仍不理想:

library(ggpattern)

set.seed(123)
colors <- c("red", "blue", "green", "yellow", "purple", "orange")
favorite_color <- replicate(nrow(nc), {
    sample_size <- sample(1:3, 1)
    sample(colors, sample_size, replace = FALSE)
})

my_df <- data.frame(
    NAME = nc$NAME, 
    stringsAsFactors = FALSE
)

for(i in 1:3) {
    my_df[[paste0("color", i)]] <- sapply(favorite_color, function(x) if(length(x) >= i) x[i] else NA)
}

my_df$color_count <- sapply(favorite_color, length)

nc_merged <- merge(nc, my_df, by = "NAME", all.x = TRUE)

nc_merged$pattern <- ifelse(nc_merged$color_count == 2, "stripe", "crosshatch")

ggplot() +
    # Layer for counties with a single color
    geom_sf(data = subset(nc_merged, color_count == 1), 
            aes(fill = color1), 
            color = "white") +
    # Layer for counties with two colors
    geom_sf_pattern(data = subset(nc_merged, color_count == 2),
                    aes(fill = color1, 
                        pattern_fill = color2),
                    pattern = "stripe",
                    pattern_angle = 45,
                    color = "white",
                    pattern_density = 0.5,
                    pattern_spacing = 0.01,
                    pattern_key_scale_factor = 0.6) +
    # Layer for counties with three colors
    geom_sf_pattern(data = subset(nc_merged, color_count == 3),
                    aes(fill = color1,
                        pattern_fill = color2),
                    pattern = "crosshatch",
                    pattern_angle = 45,
                    color = "white",
                    pattern_density = 0.5,
                    pattern_spacing = 0.01,
                    pattern_key_scale_factor = 0.6) +
    geom_sf_pattern(data = subset(nc_merged, color_count == 3),
                    aes(pattern_fill = color3),
                    pattern = "crosshatch",
                    pattern_angle = 135,
                    color = NA,
                    pattern_density = 0.5,
                    pattern_spacing = 0.01) +
    scale_fill_identity() +
    theme_minimal() +
    labs(title = "Favorite Color by County (with Patterns for Ties)")

改进后的ggpattern平局县地图

可行解决方案:颜色混合(RGB平均值法)

通过将颜色转换为RGB数值,对平局的颜色取平均值生成混合色,具体代码如下:

library(sf)
library(dplyr)
library(ggplot2)

# 加载数据
nc <- st_read(system.file("gpkg/nc.gpkg", package = "sf"), quiet = TRUE) %>%
  st_transform(st_crs(4326)) %>%
  st_cast("POLYGON")

set.seed(123)
colors <- c("red", "blue", "green", "yellow", "purple", "orange")
favorite_color <- replicate(nrow(nc), {
    sample_size <- sample(1:3, 1)
    sample(colors, sample_size, replace = FALSE)
})

# 定义函数:将颜色列表转换为混合RGB色
mix_colors <- function(color_list) {
  if(length(color_list) == 1) return(color_list)
  # 转换为RGB矩阵并归一化到0-1范围
  rgb_matrix <- sapply(color_list, function(col) col2rgb(col) / 255)
  # 计算各通道平均值
  avg_rgb <- apply(rgb_matrix, 1, mean)
  # 转换回十六进制颜色
  rgb(avg_rgb[1], avg_rgb[2], avg_rgb[3])
}

# 生成混合色列
my_df <- data.frame(
  NAME = nc$NAME,
  mixed_color = sapply(favorite_color, mix_colors),
  original_colors = sapply(favorite_color, function(x) paste(x, collapse = ", "))
)

nc_merged <- merge(nc, my_df, by = "NAME", all.x = TRUE)

# 绘制地图
ggplot(data = nc_merged) +
  geom_sf(aes(fill = mixed_color), color = "white") +
  scale_fill_identity(name = "Color Combination", 
                      labels = nc_merged$original_colors,
                      guide = "legend") +
  theme_minimal() +
  labs(title = "Favorite Color by County (Mixed Colors for Ties)")

该方案通过RGB通道平均值生成混合色,既保留了平局县的颜色信息,又保证了地图的可读性,图例可展示每个县的原始颜色组合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:17:34