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

基于四色定理实现地图非相邻区域自动四色填充的技术咨询

基于四色定理实现地图非相邻区域自动四色填充的技术咨询

嘿,这个问题问得太贴合实际需求了——四色定理的落地应用确实是地图可视化里的经典痛点!你遇到的报错很正常,因为直接按State_Name作为分类变量的话,ggplot会默认给每个不同的邦/地区分配独立颜色,但你只有4种,自然不够用。要实现四色填充,核心得基于空间相邻关系来分配颜色,而不是按类别来,咱们一步步来搞定:

第一步:先获取区域的相邻关系

首先得让程序知道哪些区域是互相接壤的,这是四色填充的基础。用sf包的st_touches()函数就能轻松拿到这个关系:

library(sf)
library(ggplot2)
library(RColorBrewer)

# 计算每个区域的相邻矩阵(sparse=FALSE返回完整矩阵,方便后续处理)
adj_matrix <- st_touches(india_state_dist, sparse = FALSE)

这个矩阵里,adj_matrix[i,j]为TRUE就表示第i个区域和第j个区域是相邻的。

第二步:用贪心算法分配颜色

四色定理告诉我们,任何平面地图都能用4种颜色填满且相邻区域颜色不同,而贪心算法就能完美实现这个逻辑——逐个给区域分配第一个不被邻居使用的颜色就行。咱们写个简单的函数来做这件事:

assign_colors <- function(adj_matrix, num_colors = 4) {
  n_regions <- nrow(adj_matrix)
  color_assignment <- rep(NA, n_regions)
  
  # 先给第一个区域分配第一种颜色
  color_assignment[1] <- 1
  
  # 遍历剩下的区域,逐个分配可用颜色
  for (i in 2:n_regions) {
    # 拿到当前区域所有已分配颜色的邻居的颜色
    neighbor_colors <- color_assignment[adj_matrix[i, ]]
    neighbor_colors <- neighbor_colors[!is.na(neighbor_colors)]
    
    # 挑第一个没被邻居用的颜色
    available_colors <- setdiff(1:num_colors, neighbor_colors)
    color_assignment[i] <- available_colors[1]
  }
  
  return(color_assignment)
}

# 给你的地图区域分配颜色ID
color_ids <- assign_colors(adj_matrix)
# 加载你想用的4种颜色
colors <- brewer.pal(4, "Set1")

第三步:用分配好的颜色画图

现在直接用分配的color_ids作为填充变量就行,再也不会报颜色不够的错了:

ggplot() +
  geom_sf(data = india_state_dist, aes(fill = factor(color_ids))) +
  scale_fill_manual(values = colors, name = "Color") +
  theme_minimal()

小提示

如果你的地图里有一些“飞地”(比如和主体不接壤的小块区域),或者你想把共享一个点的区域也算作相邻,可以把st_touches()换成st_intersects(),不过一般地图可视化里用st_touches()(共享边界才算相邻)就足够啦。

备注:内容来源于stack exchange,提问作者Damitr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 13:08:18