Search code examples
rprobability-densitykernel-densityspatstat

Kernel Density Estimation - change legend scale to density per m²


I have calculated a Kernel Density Estimation (KDE) for a species in R, i am using the ants data set (ant nests) from spatstat for simplicity here, and i would like to have a legend scale with the number of ant nest per measurement unit (e.g. m²). If I understood correctly the KDE legend displays the probability density between 0 and 1, how can I translate this probability in "real-world" densities, for example points (ant nests) per m²?

enter image description here

Here the example:

require("spatstat")
data(ants)
dat <- ants

# estimate bandwith
h_cox <- bw.diggle(dat)

# calculate KDE
kd_cox <- density(dat, h_cox, diggle=TRUE, se=TRUE, eps=diff(dat$window$xrange)/500)

# Plot KDE, contours and points
plot(kd_cox$estimate, main="KDE ants bw.diggle")
contour(kd_cox$estimate, labels="", add=TRUE, col=gray(.5)) 
points(dat)

Solution

  • Thanks for a clear question with example data.

    library(spatstat)
    

    Original ants data are given in 0.5 feet units:

    ants
    #> Marked planar point pattern: 97 points
    #> Multitype, with levels = Cataglyphis, Messor 
    #> window: polygonal boundary
    #> enclosing rectangle: [-25, 803] x [-49, 717] units (one unit = 0.5 feet)
    

    Thus the code in the original post gives the intensity in number of points per “square 0.5 feet”, which would be points per “quarter square foot”. Use rescale without arguments to get usual feet:

    ants_ft <- rescale(ants)
    ants_ft
    #> Marked planar point pattern: 97 points
    #> Multitype, with levels = Cataglyphis, Messor 
    #> window: polygonal boundary
    #> enclosing rectangle: [-12.5, 401.5] x [-24.5, 349.5] feet
    

    Use rescale with conversion factor and name to get metre:

    ants_m <- rescale(ants_ft, 3.2808399, "m")
    ants_m
    #> Marked planar point pattern: 97 points
    #> Multitype, with levels = Cataglyphis, Messor 
    #> window: polygonal boundary
    #> enclosing rectangle: [-3.81, 122.3772] x [-7.4676, 106.5276] m
    

    Area of study region and average numer of points per square metre:

    area(ants_m)
    #> [1] 9962.028
    intensity(ants_m)
    #> Cataglyphis      Messor 
    #> 0.002911054 0.006825920
    intensity(unmark(ants_m))
    #> [1] 0.009736973
    

    Rerunning the original code with dat <- ants_m gives you the estimated intensity in number of points per square metre:

    dat <- ants_m
    # estimate bandwith
    h_cox <- bw.diggle(dat)
    #> Warning: Berman-Diggle Cross-Validation criterion was minimised at right-hand
    #> end of interval [0, 7.11]; use argument 'hmax' to specify a wider interval for
    #> bandwidth 'sigma'
    # calculate KDE
    kd_cox <- density(dat, h_cox, diggle=TRUE, se=TRUE, eps=diff(dat$window$xrange)/500)
    # Plot KDE, contours and points
    plot(kd_cox$estimate, main="KDE ants bw.diggle")
    contour(kd_cox$estimate, labels="", add=TRUE, col=gray(.5)) 
    points(dat)