I have created a map that iterates through counties and adds a color and a pattern based on the great ggpattern r package, however I cannot figure out how to create a legend to add to the map with the cooresponding colors and hex patterns. The reason i'm iterating and adding each individual county is so i can eventually control which patterns go with certain counties. If there is a better way i am open to that as well!
library(ggplot2)
library(sf)
library(tidyverse)
library(ggpattern)
library(cowplot)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc<-nc%>%mutate(row_id=row_number())
ids=unique(nc$row_id)
##pattern
df1 <- data.frame(
x = rep(1:6, 9),
y = rep(1:9, each=6),
name = gridpattern::names_magick,
stringsAsFactors = FALSE
)
df1<-df1%>%mutate(row_id=row_number())
df_color<-data.frame()
pattern_rand_df_final<-data.frame()
p1 <- ggplot()
ids=1:10
for(id in ids){
df <- nc%>%filter(id==row_id)
x=paste(sample(0:255,size=1,replace=TRUE),collapse=" ")
y=paste(sample(0:255,size=1,replace=TRUE),collapse=" ")
z=paste(sample(0:255,size=1,replace=TRUE),collapse=" ")
zz=rgb(x,y,z, maxColorValue = 255)
df_color<<-rbind(df_color,zz)
df_color=df_color%>%mutate(row_id=row_number())
df_color_f<- df_color%>%filter(row_id==id)
colnames(df_color_f)[1]='fill_color'
num_rand=sample(1:54,1)
pattern_rand_df_final<<-rbind(pattern_rand_df_final,num_rand)
pattern_rand_df_final=pattern_rand_df_final%>%mutate(row_id=row_number())
pattern_rand_df_final_filter<- pattern_rand_df_final%>%filter(row_id==id)
colnames(pattern_rand_df_final_filter)[1]='random_pattern'
df1_f<-df1%>%filter(row_id==pattern_rand_df_final_filter$random_pattern)
p1<-p1 + geom_sf_pattern(data = df, fill=df_color_f$fill_color, color = "black",pattern='magick',
pattern_type = I(df1_f$name))
}
##this creates the map
p1
legend_df<-full_join(df_color,pattern_rand_df_final)
colnames(legend_df)[1]='color_fill'
colnames(legend_df)[3]='hex_fill_number_id'
legend_df<-left_join(legend_df,df1%>%select(name,row_id),by=c("hex_fill_number_id"="row_id"))
###this is the legend information i would like to add using cowplot
legend_df<-left_join(legend_df,st_drop_geometry(nc)%>%select(row_id,NAME)%>%rename(county=NAME))
As a general rule, if you want to have a legend then map on aesthetics. This said, one option and a probably easier approach would be to create two named vectors of fill colors and patterns, which assign colors and or patterns to county names. Then map the county NAME
on the fill
and pattern_type
aes inside aes()
and apply your desired colors and patterns using scale_xxx_manual
:
library(ggplot2)
library(sf)
library(ggpattern)
set.seed(123)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
pal_color <- rgb(
sample(255, nrow(nc), replace = TRUE),
sample(255, nrow(nc), replace = TRUE),
sample(255, nrow(nc), replace = TRUE),
maxColorValue = 255
)
n_counties <- 10
dat_map <- nc |>
head(n_counties)
pal_color <- pal_color[seq_len(n_counties)]
pal_pattern <- sample(gridpattern::names_magick, n_counties)
names(pal_color) <- names(pal_pattern) <- dat_map$NAME
ggplot() +
geom_sf_pattern(
data = dat_map,
aes(
fill = NAME,
pattern_type = NAME
),
color = "black", pattern = "magick",
) +
scale_fill_manual(values = pal_color) +
scale_pattern_type_manual(values = pal_pattern) +
theme(legend.position = "bottom")