Home > Software design >  How to visualize only specific geographic area with ggplot2?
How to visualize only specific geographic area with ggplot2?

Time:02-04

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'))

states, baseline colors

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'))

filtered states, relative colors changed

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()

filtered states, colors same as the

Notice that I'm using inline ~ rlang-style functions for subsetting the data; this is my convention but is not required.

  • Related