ggmapkernel-densityspatstat

Difficulty in Visualizing Spatial Density with ggplot2 and sf Package


I'm currently working on visualizing the spatial density. However, I'm facing an issue where the density plot doesn't adequately represent areas with few sampled points, particularly in regions like Utah in this example where there are sparse data points.

sf_points <- data.frame(
  lat = c(39.52, 39.62, 40.03, 40.00, 39.93, 39.94, 40.12, 40.54, 35.78, 35.77),
  lon = c(-116.32, -116.00, -116.42, -116.40, -116.41, -116.41, -116.59, -116.56, -111.89, -111.51)
)

This is my method:


library(sf)
library(dplyr)
library(ggplot2)
library(spatstat)

sf_points<-dfst_as_sf%>%
   (coords = c("lon", "lat"), crs = 4326) %>%
    st_transform(32650)

ppp_points <- as.ppp(sf_points)
Window(ppp_points) <- as.owin(usa_map)

par(mar = rep(0, 4))
plot(ppp_points, main = "")


density_spatstat <- density(ppp_points, dimyx = 256)

density_stars <- stars::st_as_stars(density_spatstat)

density_sf <- st_as_sf(density_stars) %>%
  st_set_crs(32650)



And then plotting


ggplot(usa_map) +
  geom_sf(data = density_sf, aes(fill = v), col = NA) +
theme_bw() +
  ggthemes::theme_map()+ geom_sf(data = st_boundary(usa_map))+
  coord_sf(crs = st_crs("+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs"), datum = NA)+scale_fill_viridis_c(option = "c")


Despite using the scale_fill_viridis_c function to adjust the color scheme, the density plot doesn't provide sufficient visual contrast to distinguish areas with varying densities of sampled points. I would like to enhance the visualization so that even regions with few sampled points are clearly discernible.

I'm seeking advice on how to adjust the color scheme or apply alternative visualization techniques that can better highlight variations in density, particularly in regions with sparse data points like Utah.

Any suggestions or guidance would be greatly appreciated. Thank you!


Solution

  • I can't reproduce your example (usa_map is not found, and there's a syntax error somewhere in the code)

    You don't say exactly what is wrong with the graphics output (other than that it "does not provide sufficient contrast").

    The input parameter which has the biggest effect on the result is the smoothing bandwidth sigma. This should be specified in the call to density(). Your code does not specify sigma so the code uses the default value of sigma which may not be appropriate in this case. The call is dispatched to the method density.ppp in the spatstat.explore package. I suggest you read the help file for density.ppp for guidance.

    With very sparse data it is possible that the algorithm produces some pixel values which are negative (but extremely small) due to numerical artifacts. This could affect the graphics display if the graphics code is expecting nonnegative pixel values: it may render negative values as blanks. You can check whether any small negative values were in fact returned by typing range(density_spatstat) or summary(density_spatstat) or any(density_spatstat < 0). You can set positive=TRUE in the call to density to remove such values. See the help file for density.ppp.

    There are also numerous alternatives to density.ppp which use adaptive smoothing, which may be more appropriate for your data. Again, see the help file for cross-references.