Introduction
Broadly the Wombling algorithm traverses a 'landscape' (for example species richness at different degree squares) and describes the the landscape in terms of the Rate of Change (m
) (think slope/gradient) and Direction of Change (θ
) (direction of slope). For a more in-depth overview you can refer to the preprint available at the following 10.32942/osf.io/sjxd8, otherwise follow along for a high-level overview is roughly outlined in the figure below.
Although the wombling algorithm (as implemented here) is designed to work with two-dimensional i.e. planar data (as delimited by $x$ and $y$), it is beneficial to view this plane as a three-dimensional object (or series of curves), as shown in panel A of the figure below. Here the 'amplitude' of the curvature of the plane is determined by the value of $z$ and the rate and direction of change is calculated by using the first-order partial derivative ($\partial$) of the surface (curve) as described by $f(x,y)$ (panel B). Using the rate of change it is also possible to identify candidate boundaries (dashed line in panel C) in the landscape that indicate 'shifts' from one state to another.
Both rate and direction of change are calculated by interpolating points in a given search window which (depending on how the points are arranged in space), and can be done in two ways.
Lattice Wombling: For points that are regularly arranged in space the search window is 2 × 2 points. Note that the wombled landscape will be will be smaller than the original landscape (A) due to the interpolation process i.e. where we originally had an $n \times r$ grid we now have an ($n$ - 1)($r$ - 1) sized grid.
Triangulation Wombling: For points that irregularly arranged in space nearest neigbours are found using delaunay triangualtion and interpolation is between 3 points.
In this example, we will see how the SpatialBoundaries.jl
package works (as well as interpreting the rates and direction of change), by taking a random mid-point displacement landscape, and measuring its rate and direction of change.
using SpatialBoundaries
using NeutralLandscapes
using StatsPlots
[ Info: Loading NeutralLandscapes support for SimpleSDMLayers.jl...
We will set a few options for the default plots:
default(; dpi=500, size=(600, 600), aspectratio=1, c=:davos, frame=:box)
The landscape generation is done using the NeutralLandscapes
package, and we will pick a 500x500 grid:
landscape_size = (500, 500)
landscape = rand(MidpointDisplacement(0.75), landscape_size...)
500×500 Matrix{Float64}:
0.665152 0.664671 0.667763 0.66922 … 0.617248 0.613902 0.613422
0.667868 0.671743 0.670004 0.66171 0.617561 0.624433 0.612967
0.669538 0.668893 0.673951 0.663436 0.627919 0.631682 0.611113
0.683372 0.679839 0.675221 0.666175 0.627013 0.618984 0.613375
0.691415 0.678976 0.671105 0.660924 0.613832 0.606988 0.61499
0.692187 0.688199 0.687575 0.668852 … 0.61513 0.605776 0.613685
0.693575 0.689036 0.683301 0.677309 0.625288 0.611619 0.617025
0.693324 0.696267 0.697749 0.689174 0.622282 0.616498 0.612927
0.692942 0.69655 0.699523 0.692997 0.622394 0.620407 0.61698
0.683474 0.690273 0.689848 0.693124 0.624013 0.628963 0.617526
⋮ ⋱
0.241842 0.247224 0.259306 0.266778 0.619564 0.617161 0.628607
0.250904 0.254732 0.254984 0.261328 0.600411 0.612608 0.624796
0.239697 0.24827 0.249124 0.263223 0.594473 0.601418 0.596282
0.240378 0.239421 0.25115 0.254957 0.575091 0.579234 0.585857
0.237752 0.243669 0.246735 0.251678 … 0.551648 0.555195 0.561405
0.242826 0.239218 0.247406 0.249517 0.528903 0.52808 0.545261
0.24685 0.254322 0.252129 0.257679 0.528605 0.535301 0.535294
0.257274 0.259232 0.26375 0.261993 0.520461 0.529642 0.537611
0.259036 0.266626 0.267232 0.266099 0.504079 0.507632 0.509753
By default, lattice wombling will assume that the cells have the same size, which is 1/n (where n is the number of cells on each side), but you can specify your own x
and y
arguments.
We can take a quick peek at the landscape:
heatmap(landscape)
Getting the lattice wombling is done with
W = wombling(landscape);
The resulting LatticeWomble
object has fields for the rate of change (m
), the direction of change in degrees (θ
), and the values of the centers of the cells at x
and y
(note that the grid of rates of change is one cell smaller than the original grid!). These points are in a grid so the Lattice Wombling function was used - note that wombling()
will select the appropriate algorithm based on data input.
Let's have a look at the rate of change:
heatmap(W.m, c=:tokyo, clim=(0, maximum(W.m)))
The rate of change informs us on the potential for there to be a boundary (zone of change) within a window. Cells with a high rate of change are indicative of large differences (changes) in the landscape 'topology' and are suggestive of a boundary as we shift from one 'state' to another.
The direction of change is also given, and is expressed a wind direction; for instance, an angle of 180° means that the value is smaller in the South, and larger in the North:
heatmap(W.θ, c=:romaO, clim=(0., 360.))
The direction of change is not the direction the boundary would be if you were to draw it on the landscape but rather the direction the rate of change is 'moving in'. This means it is possible to think of and use the direction of change independently of calculating boundaries per se and can be used to inform how the landscape is behaving/changing in a more 'continuous' way as opposed to discrete zones/boundaries. For example if changes in species richness are more gradual (rate of change is near constant) but the direction of change is consistently South-North (i.e. 180°) we can still infer that species richness is 'uniformly' increasing in a South-North direction.
A note on outputs: The new $x$ and $y$ co-ordinates correspond to latitude and longitude respectively (which is the opposite of what one might expect).