如何用R的sf+ggplot2包手动修改韦恩图圆圈及交集区域颜色?
自定义sf + ggplot2韦恩图的圆圈与交集颜色
问题描述
使用sf和ggplot2绘制韦恩图时,希望手动修改各个圆圈以及两两圆圈交集区域的颜色,但当前代码中scale_fill_manual仅能控制圆圈颜色,交集区域被硬编码为白色,无法通过统一的颜色映射修改。
解决方案
要实现自定义所有区域的颜色,有两种实用思路:
- 统一映射法:给交集区域也添加
fill_id标识,将所有区域(圆圈+交集)纳入同一颜色映射体系,通过scale_fill_manual统一控制。 - 单独指定法:保留圆圈的颜色映射,直接为每个交集图层单独指定
fill参数。
方法1:统一颜色映射
先为交集区域添加fill_id,再通过scale_fill_manual定义所有区域的颜色:
library(ggplot2) library(dplyr) library(sf) create_circle_sf <- function(x, y, radius, label, fill_id) { st_point(c(x, y)) %>% st_buffer(radius) %>% st_sfc(crs = 4326) %>% st_sf(label = label, fill_id = fill_id, geometry = .) } # 计算半径 r1 <- sqrt(6000 / pi) r2 <- sqrt(2000 / pi) r3 <- sqrt(2000 / pi) # 创建圆圈sf对象 circle1 <- create_circle_sf(0, 0, r1, "Party Representatives", "A") circle2 <- create_circle_sf(14, 0, r2, "Unique parties", "B") circle3 <- create_circle_sf(-13, 0, r3, "Client Companies", "C") circles_all <- bind_rows(circle1, circle2, circle3) # 创建交集并添加fill_id intersect12 <- st_intersection(circle1, circle2) %>% mutate(fill_id = "AB") intersect13 <- st_intersection(circle1, circle3) %>% mutate(fill_id = "AC") intersect23 <- st_intersection(circle2, circle3) %>% mutate(fill_id = "BC") # 定义所有区域的自定义颜色 custom_colors <- c( "A" = "#77bca2", # 代表方圆圈 "B" = "#FFEB3B", # 政党圆圈 "C" = "#FF9800", # 客户公司圆圈 "AB" = "#4CAF50", # 代表方+政党交集 "AC" = "#2196F3", # 代表方+客户公司交集 "BC" = "#F44336" # 政党+客户公司交集 ) # 标签数据 label_df <- data.frame( x = c(0, 14, -13), y = c(0, 0, 0), label = c("Party Representatives: 41", paste0("Unique\n Parties: ", 20), paste0("Unique\nClient\nCompanies: ", 30)) ) # 绘图 ggplot() + geom_sf(data = circles_all, aes(fill = fill_id), alpha = 0.8) + geom_sf(data = intersect12, aes(fill = fill_id), alpha = 0.8) + geom_sf(data = intersect13, aes(fill = fill_id), alpha = 0.8) + geom_sf(data = intersect23, aes(fill = fill_id), alpha = 0.8) + geom_text(data = label_df, aes(x = x, y = y, label = label), size = 4.5, fontface = "bold", lineheight = 0.9) + scale_fill_manual(values = custom_colors) + theme_void() + coord_sf() + theme(legend.position = "none")
方法2:单独指定交集颜色
如果只想修改交集颜色,保持圆圈的颜色映射,直接为每个交集图层指定fill参数即可:
# 初始化代码同方法1,此处省略 # 定义圆圈颜色 circle_colors <- c("A" = "#77bca2", "B" = "#FFEB3B", "C" = "#FF9800") # 绘图 ggplot() + geom_sf(data = circles_all, aes(fill = fill_id), alpha = 0.8) + # 单独指定每个交集的颜色 geom_sf(data = intersect12, fill = "#4CAF50", alpha = 0.8) + geom_sf(data = intersect13, fill = "#2196F3", alpha = 0.8) + geom_sf(data = intersect23, fill = "#F44336", alpha = 0.8) + geom_text(data = label_df, aes(x = x, y = y, label = label), size = 4.5, fontface = "bold", lineheight = 0.9) + scale_fill_manual(values = circle_colors) + theme_void() + coord_sf() + theme(legend.position = "none")
注意事项
- 图层顺序不能乱:必须先绘制底层的圆圈,再绘制上层的交集区域,这样交集才能覆盖圆圈的重叠部分。
alpha参数用于调整透明度,能让重叠区域的层次更清晰。
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

