rggplot2legendggrough

How to get legend box to show up


Say that I create a choropleth map of NC using this code:

library(ggplot2)
library(sf)
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
b <- ggplot(nc) +
    geom_sf(aes(fill = AREA))
b

enter image description here

The legend looks as it should.

I then use the code from Paul's answer to this question (How to shade shapes, which is itself based on Unable to replicate this ggplot2 plot) in order to create a ggrough (https://github.com/xvrdm/ggrough) version of the plot.

#devtools::install_github("xvrdm/ggrough")
library(ggrough)
library(magrittr)

#In the popup window, paste this so that parse_rough will use parse_sf for GeomSf.
function (svg, geom) 
{
    rough_els <- list()
    if (geom %in% c("GeomCol", "GeomBar", "GeomTile", 
                    "Background")) {
        rough_els <- append(rough_els, parse_rects(svg))
    }
    if (geom %in% c("GeomArea", "GeomViolin", "GeomSmooth", 
                    "Background")) {
        rough_els <- append(rough_els, parse_areas(svg))
    }
    if (geom %in% c("GeomPoint", "GeomJitter", "GeomDotPlot", 
                    "Background")) {
        rough_els <- append(rough_els, parse_circles(svg))
    }
    if (geom %in% c("GeomLine", "GeomSmooth", "Background")) {
        rough_els <- append(rough_els, parse_lines(svg))
    }
    if (geom %in% c("Background")) {
        rough_els <- append(rough_els, parse_texts(svg))
    }
    if (geom %in% c("GeomSf")) {
        rough_els <- append(rough_els, parse_sf(svg))
    }
    purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom))
}

parse_sf <- function (svg) {
    shape <- "path"
    keys <- NULL
    ggrough:::parse_shape(svg, shape, keys) %>% {
        purrr::map(., 
                   ~purrr::list_modify(.x, 
                                    points = .x$d, 
                                    shape = "path"
                   ))
    }
}

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
b <- ggplot(nc) +
    geom_sf(aes(fill = AREA))
b


options <- list(GeomSf=list(fill_style="hachure", 
                            angle_noise=0.5,
                            gap_noise=0.2,
                            gap=1.5,
                            fill_weight=1))
get_rough_chart(b, options)

This produces:

enter image description here

However, the color box part of the legend now is missing. Is there a way to display it?

Note that in some cases, the legend does work. I am not sure if it a discrete vs. continuous thing, but the legend in this discretely-colored ggrough plot in Z.Lin's answer to this question works (Unable to replicate this ggplot2 plot).


Solution

  • It looks as if ggrough or rough.js can't deal with guide_colorbar. Hence, one option to get a legend would be to switch to scale_fill_binned which automatically does some binning of the fill variable and uses guide_colorsteps:

    library(ggplot2)
    library(ggrough)
    
    nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
    b <- ggplot(nc) +
      geom_sf(aes(fill = AREA)) +
      scale_fill_binned()
    
    options <- list(GeomSf = list(
      fill_style = "hachure",
      angle_noise = 0.5,
      gap_noise = 0.2,
      gap = 1.5,
      fill_weight = 1
    ))
    get_rough_chart(b, options, width = 10, height = 5)
    

    enter image description here

    As an alternative you can stick with the color gradient for the map but switch to e.g. guide_colorsteps for which I would suggest to explicitly set the limits for the scale (otherwise I get an additional grey box for the limits, which might be a bug). Finally, a third approach would be to manually discretize the fill variable and use a discrete fill scale.

    library(ggplot2)
    library(ggrough)
    
    nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
    b <- ggplot(nc) +
      geom_sf(aes(fill = AREA)) +
      scale_fill_gradient(
        guide = guide_colorsteps(),
        limits = c(0, .25)
      )
    
    options <- list(GeomSf = list(
      fill_style = "hachure",
      angle_noise = 0.5,
      gap_noise = 0.2,
      gap = 1.5,
      fill_weight = 1
    ))
    get_rough_chart(b, options, width = 10, height = 5)
    

    enter image description here