There are lots of different ways to plot density maps. Let’s look at a few.

Load some example data

library(Distance)
library(dsm)
load("spermwhale.RData")
df_hn <- ds(data=dist, truncation=6000, key="hn", adjustment=NULL)
my_dsm <- dsm(count~s(x,y, bs="ts") +
                    s(Depth, bs="ts"),
              df_hn, segs, obs,
              family=tw())
# make a prediction
predgrid$density <- predict(my_dsm, newdata=predgrid, offset=predgrid$off.set)

Heatmap

1. continuous heatmap

library(ggplot2)
p <- ggplot(predgrid) +
      geom_tile(aes(x=x, y=y, fill=density, width=10*1000, height=10*1000)) +
      coord_equal() +
      theme_minimal() +
      scale_fill_viridis_c()
print(p)

plot of chunk heatmap

2. “discrete” heatmap

We can “discretize” the map, with levels. How we do this is some kind of magic, so let’s just do something arbitrary for now…

predgrid_d <- predgrid
predgrid_d$densityd <- cut(predgrid_d$density, c(0, 0.1, 0.5, 1, 2, 3.1))
p <- ggplot(predgrid_d) +
      geom_tile(aes(x=x, y=y, fill=densityd, width=10*1000, height=10*1000)) +
      coord_equal() +
      theme_minimal() +
      scale_fill_viridis_d()
print(p)

plot of chunk heatmap-d

Contour

p <- ggplot(predgrid) +
      geom_contour(aes(x=x, y=y, z=density), colour="black") +
      coord_equal() +
      theme_minimal() +
      scale_fill_viridis_c()
print(p)

plot of chunk contour

There are some (fairly fiddly) ways to get contour labels on the plot. For example:

library(directlabels)
## Warning: package 'directlabels' was built under R version 3.4.4
## 
## Attaching package: 'directlabels'
## The following object is masked from 'package:nlme':
## 
##     gapply
p <- ggplot(predgrid) +
      geom_contour(aes(x=x, y=y, z=density, colour = ..level..)) +
      coord_equal() +
      theme_minimal() +
      scale_fill_viridis_c()
p3 <- direct.label(p, list("far.from.others.borders", "calc.boxes",
                           "enlarge.box", box.color = NA, fill = "transparent",
                           "draw.rects"))
print(p3)

plot of chunk contour-lab

ggridges

There are some different options for how to scale the response here…

1. density

library(ggridges)
## Warning: package 'ggridges' was built under R version 3.4.4
## 
## Attaching package: 'ggridges'
## The following object is masked from 'package:ggplot2':
## 
##     scale_discrete_manual
p <- ggplot(predgrid) +
      geom_ridgeline(aes(x=x, y=density*10000+y, group=y, height=10*1000), fill=NA) +
      coord_equal() +
      labs(x="x", y="y") +
      theme_minimal()
print(p)

plot of chunk ridge

2. density/max(density)

p <- ggplot(predgrid) +
      geom_ridgeline(aes(x=x, y=density/max(density)*10000+y, group=y, height=10*1000), fill=NA) +
      coord_equal() +
      labs(x="x", y="y") +
      theme_minimal()
print(p)

plot of chunk ridge-max

Dot density

There seems to be a few ways of doing this… Many seem to involve faffing around with sampling within polygons.

1. Dave’s ad hoc way that’s probably bad

# sample from a poisson with intensity==density
ndot <- rpois(rep(1,nrow(predgrid)), predgrid$density)
# make a new data set with locations of "observations" above
# some of the predgrid gets dropped, the rest multiplied
rep_grid <- predgrid[rep(1:nrow(predgrid), ndot), ]

# plot using jitter to stop overplotting
p <- ggplot(rep_grid, aes(x=x, y=y)) +
      coord_equal() +
      theme_minimal() +
      geom_jitter(width=10*1000, height=10*1000, size=0.05, fill="black")
print(p)

plot of chunk dave-lazy

This changes each time, so we could make a grid of “possible” dot maps too. But I think that gets away from the true source of variation (parameter/hyperparameter estimates), and instead focuses on the rpois/jitter variation.