Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EmpiricalTransiogram #28

Merged
merged 17 commits into from
Oct 17, 2024
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
TableTransforms = "0d432bfd-3ee1-4ac1-886a-39f05cc69a3e"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

Expand Down Expand Up @@ -49,6 +50,7 @@ Random = "1.9"
Setfield = "1.0"
StaticArrays = "1.9"
Statistics = "1.9"
TableTransforms = "1.33"
Tables = "1.6"
Unitful = "1.11"
julia = "1.9"
69 changes: 67 additions & 2 deletions ext/transioplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,81 @@
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

# ----------
# EMPIRICAL
# ----------

function transioplot(
t::EmpiricalTransiogram;
# common transiogram options
color=:slategray,
size=1.5,
maxlag=nothing,
levels=nothing,

# empirical transiogram options
pointsize=12,
showtext=true,
textsize=12,
showhist=true,
histcolor=:slategray
)
# number of labels
L = Base.size(t.ordinates, 1)

# retrieve labels
l = isnothing(levels) ? (1:L) : levels

fig = Makie.Figure()
for i in 1:L, j in 1:L
lᵢ, lⱼ = l[i], l[j]
ax = Makie.Axis(fig[i, j])

# retrieve coordinates and counts
x = t.abscissas
y = t.ordinates[i, j]
n = t.counts

# discard empty bins
x = x[n .> 0]
y = y[n .> 0]
n = n[n .> 0]

# visualize frequencies as bars
if showhist
f = n * (maximum(y) / maximum(n)) / 10
Makie.barplot!(ax, x, f, color=histcolor, alpha=0.3, gap=0.0)
end

# visualize transiogram
Makie.scatterlines!(ax, x, y, color=color, markersize=pointsize, linewidth=size, label="$lᵢ → $lⱼ")

# visualize text counts
if showtext
text = string.(n)
Makie.text!(ax, x, y, text=text, fontsize=textsize)
end

Makie.axislegend(position=i == j ? :rt : :rb)
end
fig
end

# ------------
# THEORETICAL
# ------------

function transioplot(
t::Transiogram;
# common transiogram options
color=:slategray,
size=1.5,
maxlag=nothing
maxlag=nothing,
levels=nothing
)
# effective ranges and labels
r = GeoStatsFunctions.ranges(t)
l = GeoStatsFunctions.levels(t)
l = isnothing(levels) ? (1:length(r)) : levels

# number of labels
L = length(l)
Expand Down
46 changes: 23 additions & 23 deletions ext/varioplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ function Makie.plot!(plot::VarioPlot{<:Tuple{EmpiricalVariogram}})
γ = plot[:γ]

# get the data
xyn = Makie.@lift values($γ)
x = Makie.@lift $xyn[1]
y = Makie.@lift $xyn[2]
n = Makie.@lift $xyn[3]
x = Makie.@lift $γ.abscissas
y = Makie.@lift $γ.ordinates
n = Makie.@lift $γ.counts

# discard empty bins
x = Makie.@lift $x[$n .> 0]
Expand Down Expand Up @@ -78,43 +77,44 @@ function Makie.plot!(plot::VarioPlot{<:Tuple{EmpiricalVarioplane}})
θs = Makie.@lift $v.θs

# polar radius
rs = Makie.@lift ustrip.(values($γs[1])[1])

# variogram values for all variograms
Z = Makie.@lift let
zs = map($γs) do γ
zs = ustrip.(values(γ)[2])

# handle NaN values (i.e. empty bins)
isnan(zs[1]) && (zs[1] = 0)
for i in 2:length(zs)
isnan(zs[i]) && (zs[i] = zs[i - 1])
rs = Makie.@lift ustrip.($γs[1].abscissas)

# variogram ordinates for all variograms
H = Makie.@lift let
hs = map($γs) do γ
# retrieve ordinates without units
ys = ustrip.(γ.ordinates)

# handle NaN ordinates (i.e. empty bins)
isnan(ys[1]) && (ys[1] = 0)
for i in 2:length(ys)
isnan(ys[i]) && (ys[i] = ys[i - 1])
end

zs
ys
end
reduce(hcat, zs)
reduce(hcat, hs)
end

# exploit symmetry
θs = Makie.@lift range(0, 2π, length=2 * length($θs))
Z = Makie.@lift [$Z $Z]
H = Makie.@lift [$H $H]

# hide hole at center
rs = Makie.@lift [0; $rs]
Z = Makie.@lift [$Z[1:1, :]; $Z]
H = Makie.@lift [$H[1:1, :]; $H]

# transpose for plotting
Z = Makie.@lift transpose($Z)
H = Makie.@lift transpose($H)

Makie.surface!(plot, θs, rs, Z, colormap=plot[:colormap], shading=Makie.NoShading)
Makie.surface!(plot, θs, rs, H, colormap=plot[:colormap], shading=Makie.NoShading)

# show model range
if showrange[]
ls = Makie.@lift [ustrip(range(GeoStatsFunctions.fit($rangemodel, γ))) for γ in $γs]
ls = Makie.@lift [$ls; $ls]
zs = Makie.@lift fill(maximum($Z) + 1, length($ls))
Makie.lines!(plot, θs, ls, zs, color=plot[:rangecolor])
hs = Makie.@lift fill(maximum($H) + 1, length($ls))
Makie.lines!(plot, θs, ls, hs, color=plot[:rangecolor])
end
end

Expand Down
18 changes: 9 additions & 9 deletions src/GeoStatsFunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using InteractiveUtils: subtypes
using NearestNeighbors: MinkowskiMetric
using OhMyThreads: tmapreduce
using DataScienceTraits
using TableTransforms
using CategoricalArrays
using StaticArrays
using LinearAlgebra
Expand All @@ -26,7 +27,6 @@ using Printf

import Base: merge, +, *
import Meshes: isisotropic
import CategoricalArrays: levels

# temporary fix for ⋅ with missing values
# https://github.com/JuliaLang/julia/issues/40743
Expand All @@ -36,10 +36,10 @@ import LinearAlgebra: ⋅
# utilities
include("utils.jl")

# empirical estimates
# empirical functions
include("empirical.jl")

# theoretical models
# theoretical functions
include("theoretical.jl")

# misc operations
Expand All @@ -49,15 +49,16 @@ include("plotting.jl")
include("precompile.jl")

export
# empirical variograms
# empirical functions
EmpiricalVariogram,
EmpiricalVarioplane,
EmpiricalTransiogram,

# convenience functions
DirectionalVariogram,
PlanarVariogram,
distance,
estimator,
EmpiricalVarioplane,

# theoretical function
# theoretical functions
GeoStatsFunction,
isisotropic,
metricball,
Expand Down Expand Up @@ -96,7 +97,6 @@ export
ExponentialTransiogram,

# fitting algorithms
VariogramFitAlgo,
WeightedLeastSquares,

# plotting
Expand Down
9 changes: 9 additions & 0 deletions src/empirical.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,14 @@ include("empirical/estimalgo.jl")
# END-USER TYPES AND FUNCTIONS
# -----------------------------

"""
EmpiricalFunction

An empirical function estimated from data.
"""
abstract type EmpiricalFunction end

include("empirical/variogram.jl")
include("empirical/transiogram.jl")

include("empirical/varioplane.jl")
Loading