I would like to create a Venn Diagram with sf
+ ggplot2
packages.
How to manually change the colors of the circles and the intersection regions of the two inner circles? Changing the scale fill in {ggplot2}
does not affect the colors of the circles
Initilisation
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 = .)
}
# radii from n values
r1 <- sqrt(6000 / pi)
r2 <- sqrt(2000 / pi)
r3 <- sqrt(2000 / pi)
# Add a new `fill_id` for color mapping
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")
# Combine all
circles_all <- bind_rows(circle1, circle2, circle3)
# calculate intersection (e.g., between 1 & 2)
intersect12 <- st_intersection(circle1, circle2)
intersect13 <- st_intersection(circle1, circle3)
intersect23 <- st_intersection(circle2, circle3)
# combine all
circles_all <- bind_rows(circle1, circle2, circle3)
Plot attempt
# Define color manually for each fill_id
custom_colors <- c("A" = "#77bca2", "B" = "#FFEB3B", "C" = "#FF9800")
# Circle centers and labels
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) +
# use fill_id here
geom_sf(data = intersect12, fill = "white", alpha = 0.8) +
geom_sf(data = intersect13, fill = "white", alpha = 0.8) +
geom_sf(data = intersect23, fill = "white", 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")
Two options, plot all circles, with alpha and custom fill colours, overlaps will get different fill because of alpha. Or plot the 1st circle, then overlaps, manually setting the colours without alpha, this way we can set the overlap colours manually.
gg1 <- ggplot() +
geom_sf(data = circles_all, aes(fill = fill_id), alpha = 0.3) +
scale_fill_manual(values = custom_colors, guide = "none") +
labs(title = "1") + coord_sf() + theme_void()
gg2 <- ggplot() +
geom_sf(data = circle1, fill = "#77bca2") +
geom_sf(data = intersect12, fill = "#FFEB3B") +
geom_sf(data = intersect13, fill = "#FF9800") +
geom_sf(data = intersect23, fill = "red") +
labs(title = "2") + coord_sf() + theme_void()
library(patchwork)
gg1|gg2