diff --git a/Project.toml b/Project.toml index ec0305a26..a11dea203 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SpeciesDistributionToolkit" uuid = "72b53823-5c0b-4575-ad0e-8e97227ad13b" authors = ["Timothée Poisot "] -version = "1.1.0" +version = "1.1.1" [deps] Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" diff --git a/docs/Project.toml b/docs/Project.toml index 9c6c5742f..ec80c8e30 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts index 18b0d66ac..bed6ee3f1 100644 --- a/docs/src/.vitepress/config.mts +++ b/docs/src/.vitepress/config.mts @@ -118,6 +118,7 @@ export default defineConfig({ {text: "Generating fauxcurrences", link: "/tutorials/fauxcurrences/"}, {text: "Training SDMs with SDeMo", link: "/tutorials/sdemo-introduction/"}, {text: "Mapping SDMs with SDeMo", link: "/tutorials/sdemo-vignette/"}, + {text: "VSUP and bivariate maps", link: "/tutorials/bivariate-vsup/"}, ] } ], diff --git a/docs/src/reference/CHANGELOG.md b/docs/src/reference/CHANGELOG.md index 226f6f89b..f53f7249b 100644 --- a/docs/src/reference/CHANGELOG.md +++ b/docs/src/reference/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## `v1.1.1` + +- **added** a tutorial on bivariate maps and value-suppressing uncertainty palettes + ## `v1.1.0` - **added** `boundingbox` method to get the left, right, bottom, top coordinates of an object in WGS84 diff --git a/docs/src/tutorials/bivariate-vsup.jl b/docs/src/tutorials/bivariate-vsup.jl new file mode 100644 index 000000000..3bd10698e --- /dev/null +++ b/docs/src/tutorials/bivariate-vsup.jl @@ -0,0 +1,108 @@ +# # Value-suppressing and bivariate maps + +using SpeciesDistributionToolkit +using CairoMakie +using ColorSchemes +using Statistics +CairoMakie.activate!(; type = "png", px_per_unit = 2) #hide + +# get some data + +POL = SpeciesDistributionToolkit.gadm("BEL"); +spatialextent = SpeciesDistributionToolkit.boundingbox(POL; padding = 0.1) + +# some layers + +provider = RasterData(CHELSA2, BioClim) +layers = [mask!(SDMLayer( + provider; + layer = i, + spatialextent..., + ), POL) for i in [1, 3]] + +layers = [convert(SDMLayer{Float16}, l) for l in layers] + +# unpack + +val, unc = layers + +# temperature layer + +# fig-hm +heatmap(val; axis = (aspect = DataAspect(),)) +lines!(POL[1].geometry; color = :black) +current_figure() #hide + +# now see the seasonality layer + +# fig-hm-unc +heatmap(unc; axis = (aspect = DataAspect(),)) +lines!(POL[1].geometry; color = :black) +current_figure() #hide + +# ## Value-suppressing uncertainty palette + +# function for VSUP + +function _vsup_grid(vbins, ubins, vpal; upal = colorant"#efefef55", s = 0.5, k = 1.0) + pal = fill(upal, (vbins, ubins)) + for i in 1:ubins + shrkfac = ((i - 1) / (ubins - 1))^k + subst = 0.5 - shrkfac * s / 2 + pal[:, i] .= CairoMakie.cgrad(vpal)[LinRange(0.5 - subst, 0.5 + subst, vbins)] + # Apply the mix to the uncertain color + for j in 1:vbins + pal[j, i] = ColorSchemes.weighted_color_mean(1 - shrkfac, pal[j, i], upal) + end + end + return pal +end + +# make discrete values + +function discretize(layer, n::Integer) + categories = rescale(layer, 0.0, 1.0) + n = n - 2 + map!(x -> round(x * (n + 1); digits = 0) / (n + 1), categories.grid, categories.grid) + return n * categories +end + +# VSUP test - what are the parameters + +ubins = 11 +vbins = 11 +vbin = discretize(quantize(val, vbins), vbins) +ubin = discretize(quantize(unc, ubins), ubins) + +pal = _vsup_grid(vbins, ubins, :twelvebitrainbow) + +# fig-vsup-colorpalette +f = Figure(; size = (800, 400)) +ax = Axis(f[1, 1]; aspect = DataAspect()) +heatmap!(ax, vbin + (ubin - 1) * maximum(vbin); colormap = vcat(pal...)) +hidespines!(ax) +hidedecorations!(ax) +lines!(POL[1].geometry; color = :black) +current_figure() #hide + +# fig-vsup-legend +p = PolarAxis( + f[1, 2]; + theta_0 = -pi / 2.5, + direction = -1, + tellheight = false, + tellwidth = false, +) +surface!( + p, + 0 .. π / 5, + 0 .. 1, + zeros(size(pal)); + color = reverse(pal), + shading = NoShading, +) +thetalims!(p, 0, pi / 5) +colsize!(f.layout, 1, Relative(0.7)) +current_figure() #hide + +# ## Bivariate palette