Search code examples
rsizegeospatialdistance

Set size of points based on distance to centroid in R


I am relatively new to R and spatial analysis. I want to create a map that displays all the points (which in this case correspond to the coordinates of monitoring stations) intersecting a 30km buffer around the centroid of a polygon (a county), and set the size of each point to depend on the distance between the point and the centroid.

I am able to produce the map (reported below) showing points all of the same size, color-coded depending on whether they intersect the buffer or not:

### Compute counties' centroids
counties_trans$centroid <- st_centroid(counties_trans$geometry)

#------------------------------------------------------------------------------#

### 30km centroids' buffers
counties_trans$buff <- st_buffer(counties_trans$centroid, 30000)

#------------------------------------------------------------------------------#

### Focus on specific county: Dresden: SN_L = 14, RS = 14612.

#Define bounding box of state
box = c(xmin = 703301, ymin = 5562792, xmax = 921778, ymax = 5733351)
saxony <- st_crop(counties_trans, box)

#Stations within 30km from Dresden's centroid
a <- st_intersection(saxony$buff[which(saxony$RS == "14612")], poll_st_trans$geometry)

#Stations outside 30km radius from Dresden's centroid
c <- st_difference(poll_st_trans$geometry, saxony$buff[which(saxony$RS == "14612")])

#Stations outside 30km radius from Dresden's centroid an in same State
d <- st_intersection(c, saxony$geometry[which(saxony$SN_L == "14")])

#------------------------------------------------------------------------------#

###Produce map

#Counties' borders
plot(saxony$geometry[which(saxony$SN_L == "14")], reset = FALSE)

#Dresden's centroid
plot(saxony$centroid[which(saxony$RS == "14612")], add = TRUE, pch = 20)

#30km radius
plot(saxony$buff[which(saxony$RS == "14612")], add = TRUE)

#Stations in the State outside 30km radius
plot(d, add = TRUE, pch = 24, col = 'grey')

#Stations within 30km radius
plot(a, add = TRUE, pch = 17, col = 'royalblue3', cex = dist)

#Other states
plot(saxony$geometry[which(saxony$SN_L != "14")], add = TRUE, col = 'grey')

I have computed the distance between the stations (only those that intersect the 30km buffer) and the county's centroid:

dist <- st_distance(a, saxony$centroid[which(saxony$RS == "14612")])

The part that I am missing is how to set the size of the points corresponding to the stations within the 30km radius based on the distance (well, actually since stations closer to the centroid should be bigger it would be the inverse distance, but that's easy to compute). Whether I try

plot(a, add = TRUE, pch = 17, col = 'royalblue3', cex = dist)

or

ggplot(data = saxony) +
     geom_sf() +
     geom_sf(data = a, colour = "royalblue3", size = dist)

I always get just a blue rectangle.

Would anyone know how I could do that? Thanks in advance.

Map generated by the code above


Solution

  • A couple of suggestions, st_distance returns a value in the units of your spatial reference, so try converting it to numeric before any plotting. When going the ggplot route you need to put your size variable inside an aes() call , and also specify inherit.aes=FALSE ex:

    ggplot(saxony)+
    geom_sf()+
    geom_sf(data=a, aes(size=dist), colour="royalblue3", inherit.aes=FALSE)
    

    if you are stacking multiple geoms that are having calls to fill or colour you might need to use ggnewscale package as well