I'm trying to make a graph in ggplot with a geom_sf
geometry. I can graph using scale_fill_scontinuous
, however I would like to break my caption into discrete intervals, so that instead of using scale_fill_scontinuous
, I can use scale_fill_brewer
.
I wouldn't want to create an intermediate data.frame or a vector outside of ggplot.
Currently my chart looks like this:
ggplot(data=uniao3, aes(fill=`Área Úmida`))
geom_sf()
scale_fill_continuous(limits=c(0,20000),
breaks=c(500,2000,8000,15000,20000),
labels=c('500','200-2k','2k-8k','8k-15k','15k>'),
name="Wetland")
facet_wrap(~Ano)
I would like that instead of the legend (scale) to be presented as a gradient, it would be presented as blocks similar to this one:
I know the scale_fill_brewer
command does this quite elegantly and efficiently, but how can I set my continuous variable to discrete inside ggplot?
CodePudding user response:
I would go for scale_fill_stepsn
, although there are multiple other solutions in the comments. That function takes care of discretizing a continuous variable according to your desired breaks
, and it allows to use any colours in the colours
vector (not just pre-brewed palettes).
Another advantage is that the breaks and colour vectors do not need to match up in length.
Get an sf object
library(ggplot2)
library(sf)
#> Linking to GEOS 3.8.1, GDAL 3.2.1, PROJ 7.2.1
# get sf data
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
Use scale_fill_stepsn
This is probably the easiest and most adequate way for continuous data which is cut into discrete slices.
# set breaks and colours
breaks <- seq(0, 0.3, by = 0.02)
breaks
#> [1] 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28
#> [16] 0.30
cols <- RColorBrewer::brewer.pal(9, "Spectral")
cols
#> [1] "#D53E4F" "#F46D43" "#FDAE61" "#FEE08B" "#FFFFBF" "#E6F598" "#ABDDA4"
#> [8] "#66C2A5" "#3288BD"
# plot
ggplot(data = nc, aes(fill = AREA))
geom_sf()
scale_fill_stepsn(colours = cols,
breaks = breaks,
name = "area")
theme_minimal()
Note that I assigned the breaks and cols outside of the ggplot
call for clarity, but you can of course specify them directly in the ggplot
call.
Use scale_fill_brewer
This is more adequate for real discrete data, but also works for discretized continuous data.
Here, you need to do the cutting yourself, before setting the scale. Using cut
with specified breaks
in your ggplot2
call will turn your numeric variable into a factor.
It is a bit less flexible regarding the choice of colours using scale_fill_brewer
, because you need (?) to use an existing RColorBrewer colour palette.
This way, the colour legend looks more similar to your example legend, where each cut is labelled, rather than the break points.
# plot
ggplot(data = nc, aes(fill = cut(AREA, breaks = seq(0, 0.3, by = 0.02))))
geom_sf()
scale_fill_brewer(type = "qual",
# labels = labels, # if you must
palette = "Spectral",
name = "area")
theme_minimal()
Created on 2021-09-19 by the reprex package (v2.0.1)