I'm working with ggplot2 and i'm creating a geographic representation of my country. This is the dataset and the script I'm using ( prov2022 is the shapefile for the map)
#dataset
COD_REG COD_PROV Wage
1 91 530
1 92 520
1 93 510
2 97 500
2 98 505
2 99 501
13 102 700
13 103 800
13 159 900
18 162 740
18 123 590
18 119 420
19 162 340
19 123 290
19 119 120
#script
right_join(prov2022, dataset, by = "COD_PROV") %>%
ggplot(aes(fill = `Wage`))
geom_sf()
theme_void()
scale_fill_gradientn(colors = c( 'white', 'yellow', 'red', 'black'))
It works fine, but now I'm insterested in visualizing only a specific area. If I add a filter to select the regions that have the value of the variable COD_REG > 13, I get what I was looking for but the color gradient changes.
right_join(prov2022, dataset, by = "COD_PROV") %>%
filter(COD_REG >= 13 ) %>%
ggplot(aes(fill = `Wage`))
geom_sf()
theme_void()
scale_fill_gradientn(colors = c( 'white', 'yellow', 'red', 'black'))
The color gradient of the output that I get is different if I use the filter because the colors are applied considering only the values of that specific areas and not anymore the ones of the whole country. As consequence these areas do not have anymore the colors that they had at the beggining ( I mean in the entire map that i get with the first script). I need to maintain the color gradient of the whole country, but get as output of ggplot2 only some specific areas without changing anything. How do I solve?
CodePudding user response:
Try this. I'll use fake data on the state
map from package maps
.
library(ggplot2)
library(maps)
usa <- sf::st_as_sf(map('state', plot = FALSE, fill = TRUE))
set.seed(42)
usa$val <- runif(length(usa$ID))
ggplot(usa, aes(fill = val))
geom_sf()
scale_fill_gradientn(colors = c( 'white', 'yellow', 'red', 'black'))
If we naively just filter the states we want to see, the colors change:
ggplot(usa, aes(fill = val))
geom_sf(data = ~ subset(., val > 0.5))
scale_fill_gradientn(colors = c( 'white', 'yellow', 'red', 'black'))
If we add geom_blank
, though, we can normalize the range of values from which the scale is determined. Since it still uses all of the original data, and it does nothing with it (except to update scales and limits), it "costs" nothing as far as drawing (e.g.) transparent or super-small things in order to get its way. From ?geom_blank
:
The blank geom draws nothing, but can be a useful way of ensuring
common scales between different plots. See 'expand_limits()' for
more details.
Code:
ggplot(usa, aes(fill = val))
geom_sf(data = ~ subset(., val > 0.5))
scale_fill_gradientn(colors = c( 'white', 'yellow', 'red', 'black'))
geom_blank()
Notice that I'm using inline ~
rlang-style functions for subsetting the data; this is my convention but is not required.