rggplot2labellegendbins

R ggplot: size of bins and labels in legend of binned variable


I want the legend of a binned variable discrete_var in the bottom of my figure. I want the bins on one row. The problem is that doing this results in different sizes of bins and the labels too close to each other. How can I set the size of bins, or rotate labels to be place under and vertical to the legend bins (which might do the trick)?

shp |>
  ggplot() +
  geom_sf(aes(fill = discrete_var)) +
  scale_fill_brewer(palette = 'Purples', direction = -1, na.value="grey", drop=FALSE) +
  coord_sf(expand = FALSE) +
  theme(legend.position = "bottom") +
  guides(fill=guide_legend(nrow=1,byrow=TRUE, label.position = "bottom"))

enter image description here

This is what I want, but in the bottom of the figure:

enter image description here


Solution

  • Making the legend key width wider would be one approach with legend.key.width = unit(2, "cm"):

    library(tidyverse)
    library(sf)
    #> Linking to GEOS 3.11.2, GDAL 3.6.2, PROJ 9.2.0; sf_use_s2() is TRUE
    
    map <- map_data("world")
    
    mapcols <- map |>
      count(region) |>
      mutate(
        discrete_var = cut(40 * n / max(n), breaks = seq(0, 40, 5)),
        discrete_var = gsub("\\((\\d+),(\\d+)\\]", "\\1 to \\2", discrete_var)
      )
    
    shp <-   st_as_sf(maps::map('world', plot = FALSE, fill = TRUE))
    
    shp |> 
      left_join(mapcols, by = join_by(ID == region)) |> 
      ggplot() +
      geom_sf(aes(fill = discrete_var)) +
      scale_fill_brewer(palette = 'Purples', direction = -1, na.value="grey", drop=FALSE) +
      coord_sf(expand = FALSE) +
      theme(legend.position = "bottom", legend.key.width = unit(2, "cm")) +
      guides(fill=guide_legend(nrow=1,byrow=TRUE, label.position = "bottom"))
    

    Or to put the text at an angle use legend.text = element_text(angle = 45, vjust = 0.5):

    
    shp |> 
      left_join(mapcols, by = join_by(ID == region)) |> 
      ggplot() +
      geom_sf(aes(fill = discrete_var)) +
      scale_fill_brewer(palette = 'Purples', direction = -1, na.value="grey", drop=FALSE) +
      coord_sf(expand = FALSE) +
      theme(legend.position = "bottom", legend.text = element_text(angle = 45, vjust = 0.5)) +
      guides(fill=guide_legend(nrow=1,byrow=TRUE, label.position = "bottom"))
    

    Finally, to make vertical, substitute your final line with theme(legend.position = "bottom", legend.direction = "vertical"):

    
    shp |> 
      left_join(mapcols, by = join_by(ID == region)) |> 
      ggplot() +
      geom_sf(aes(fill = discrete_var)) +
      scale_fill_brewer(palette = 'Purples', direction = -1, na.value="grey", drop=FALSE) +
      coord_sf(expand = FALSE) +
      theme(legend.position = "bottom", legend.direction = "vertical")