Search code examples
rggplot2colorsr-sf

plot map with divergent colors according to 1 variable, saturation by another, ggplot2 not working


I am working in R with a shapefile (a Large SpatialPoygonsDataFrame with 311 elements), the 1970 district map of India. I can plot a map in spplot by the value of a data column b_all (a district-specific regression coefficient) using:

brk1 = c(-130,  -5,    0,    5,  311)
spplot(distVDS_betas,zcol="b_all",at=brk1) 

I can plot a similar map by another data column t_all (each regression coefficient's t-value):

brk2 = c(0,  1.645,    1.96,    53)
spplot(distVDS_betas,zcol="t_all",at=brk2) 

What I would like to do instead is (a) plot the beta coefficients by a divergent color pattern (like orange-red going up fr/ zero, blue-purple going down fr/ zero) and then (b) saturate the colors by t-value. Can anyone help me do this?

I'm aware the ssplot is out-dated and I should be moving to ggplot2, and I'd love to learn how to use that. Tried following the code here. However, when I attempt to run this code:

ggplot(data = distVDS_betas) +
  geom_sf()

I get the error: stat_sf() requires the following missing aesthetics: geometry.

So I'm not even sure how to start with ggplot2 + sf.


Solution

  • The issue with your plotting relates to your data - your ggplot code is correct.

    In the example you are following, notice that the world object is used, where class(world) is sf.

    That means that when you inspect the world object, world$geometry gives information that ggplot uses to construct the map.

    In your code, distVDS_betas$geometry does not exist because your data likely is not an sf object. This results in the error you are seeing and prevents you from plotting.

    You have two options:

    1. Convert your data to an object of class sf
    2. Use a different geom_* that works with your object’s class

    1. Convert to ‘sf’

    This is the easiest solution.

    library(sf)
    library(ggplot2)
    
    distVDS_betas <- st_as_sf(distVDS_betas)
    
    ggplot(data = distVDS_betas) +
        geom_sf()
    

    2. Use different geom_*

    This solution depends on the structure of your data and the specific columns. This is just an example. For more info, look here

    distVDS_betas |>
        ggplot() |>
        geom_raster(aes(x = x, y = y))