Search code examples
rggplot2legend

How can I center my legend labels in ggplot?


I created a legend with a range of rates for a map. Currently, my labels appear adjacent to the breaks, I want the labels to appear adjacent to the center of each level.

Here's my code...

ggplot(state_dat, aes(fill = Rate)) +
  geom_sf() +
  scale_fill_stepsn(colours = palmap, 
                na.value = "#d0d1e6",
                breaks = c(0,5, 10, 15, 20),
                labels = c("0-5", "5-10", "10-15", "15-20", "20+"),
                limits = c(0,25)) +
  labs(title = "Rate of Heat-Related Illness per 100,000 Population")+
  theme_void()

Here's how the legend turns out.

legend for rates

How can I move those labels up so they are beside the center of each block?


Solution

  • scale_fill_stepsn probably isn't the right tool if you want to label each bin with a range. The labels on the scale are supposed to represent the value at the threshold between bins, not the bins themselves.

    You could instead use cut to bin Rate and use a manual scale:

    palmap <- c("#bfc9e2", "#9ab9d9", "#67a9cf", "#3195a4", "#0f7a72")
    labels <- c("0-5", "5-10", "10-15", "15-20", "20+")
    
    ggplot(state_dat, aes(fill = cut(Rate, c(-1, 5, 10, 15, 20, Inf), labels))) +
      geom_sf() +
      scale_fill_manual("Rate", values = rev(palmap), breaks = rev(labels)) +
      labs(title = "Rate of Heat-Related Illness per 100,000 Population") +
      guides(fill = guide_legend(override.aes = list(color = NA, linewidth = 0))) +
      theme_void() 
    

    Which will give you the following legend:

    enter image description here


    Data used

    library(sf)
    library(ggplot2)
    
    set.seed(1)
    state_dat <- st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE)
    state_dat$Rate <- sample(25, nrow(state_dat), TRUE)