Skip to content

Commit

Permalink
Add EmpiricalTransiogram (#28)
Browse files Browse the repository at this point in the history
* Refactor accumulate

* Update comments

* Add CarleEstimator

* Add :carle option to estimalgo

* Add EmpiricalTransiogram

* More refactoring

* More refactoring

* More refactoring

* Refactor ExponentialTransiogram

* Fix CarleEstimator

* Refactor varioplot

* Refactor transioplot

* Fix missing condition in accumulate

* Update 'accumulate'

* More refactoring

* Rename AccumAlgorithm -> AccumAlgo

* Rename VariogramFitAlgo -> FitAlgo

---------

Co-authored-by: Elias Carvalho <eliascarvdev@gmail.com>
  • Loading branch information
juliohm and eliascarv authored Oct 17, 2024
1 parent 7927d04 commit 42ac645
Show file tree
Hide file tree
Showing 18 changed files with 482 additions and 238 deletions.
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

0 comments on commit 42ac645

Please sign in to comment.