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 functions to spatially visualise individual and aggregate criteria for location selection #650

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9a2aa9d
Add function to prepare connectivity data for storage in resultset file
Rosejoycrocker Jan 4, 2024
a8f264b
Add connectivity data to `ResultSet` structure and constructor function
Rosejoycrocker Jan 4, 2024
4799214
Add function for creating decision matrices purely from the domain
Rosejoycrocker Nov 16, 2023
3b8a703
Move priority predecessor criteria calculation and zones criteria cal…
Rosejoycrocker Nov 16, 2023
89a3988
Add function to plot specified criteria from a decision matrix as a g…
Rosejoycrocker Nov 17, 2023
e70e1d5
Add docs for `viz.decision_matrices` and option to plot without provi…
Rosejoycrocker Nov 17, 2023
96916ca
Change `int_type` to `iv_type`
Rosejoycrocker Nov 20, 2023
0208208
Add `decison_matrices` to viz.jl
Rosejoycrocker Nov 20, 2023
deb0e61
Fix reference to undefined `zones_criteria`
Rosejoycrocker Nov 23, 2023
6918e3b
Change references to criteria weights names to reflect changes to Cri…
Rosejoycrocker Nov 27, 2023
861f7ea
Add plotting mcda aggregate score to decision matrix plots
Rosejoycrocker Nov 29, 2023
ba810a6
Change grid size definition to be square
Rosejoycrocker Nov 29, 2023
287489c
Add "decision.jl" to "analysis.jl" + formatting
Rosejoycrocker Jan 5, 2024
5da0aa8
Add "Vector{Any}" as possible type for `priority_zones` and `priority…
Rosejoycrocker Jan 5, 2024
6fac7ff
Add decison matrix creation from resultset to analysis
Rosejoycrocker Jan 5, 2024
9c6de44
Adjust to allow `TP_data` type for be `Matrix{Float32}' as it is in t…
Rosejoycrocker Jan 5, 2024
836687c
Remove `area_to_seed` as input in `decision_matrices` as no longer re…
Rosejoycrocker Jan 9, 2024
227808d
Add documentation and variable name changes in `decision_matrices` fo…
Rosejoycrocker Jan 9, 2024
b2a2a26
Formatting and delete duplicate function introduced in rebase
Rosejoycrocker Jan 11, 2024
bea727f
Add separate parameters for in and out going connectivity weights for…
Rosejoycrocker Jan 14, 2024
a0957a6
Use `criteria_params` to extract weighting labels when creating decis…
Rosejoycrocker Jan 14, 2024
ef1770e
Add optional parameter `filter_space` when creating seed matrix so th…
Rosejoycrocker Jan 14, 2024
d5b41d8
Uncomment fixing x and y lims for map (without this it is very zoomed…
Rosejoycrocker Jan 15, 2024
730f416
Revert "Uncomment lines for defining x and y lims for spatial plotting"
Rosejoycrocker Jan 15, 2024
f097986
Add `colorbar_limits` as input to `spatial` to allow limits to be adj…
Rosejoycrocker Jan 15, 2024
562bbec
Fix formatting and documentation in `viz.decision_matrices`
Rosejoycrocker Jan 16, 2024
d251b41
Add criteria plotting example to `analysis.md`
Rosejoycrocker Jan 16, 2024
9d10a4c
Use `_calc_gridsize` to calculate `n_rows` and `n_cols`
Rosejoycrocker Jan 17, 2024
78392d8
Change `criteria_weights` to `criteria_row` for clarity
Rosejoycrocker Jan 17, 2024
17b3649
Remove unnecessary `vec()`
Rosejoycrocker Jan 17, 2024
3243908
Update `Union{Float64,Float32} type to `:>Real`
Rosejoycrocker Jan 17, 2024
738380e
Revert "Update `Union{Float64,Float32} type to `:>Real`"
Rosejoycrocker Jan 18, 2024
a194638
Add `env_aggregation` as optional input for environmental summary fun…
Rosejoycrocker Jan 22, 2024
3b80d4b
Remove `ADRIA.decision` from matrix creation and criteria definition …
Rosejoycrocker Jan 22, 2024
8e18159
Add `CriteriaWeights` to imports and format
Rosejoycrocker Jan 22, 2024
e3c624b
Move `viz.decision_matrices` into `spatial.jl` and make it another in…
Rosejoycrocker Jan 22, 2024
9207094
Fix how scores are plotted (should be inside loop), add use of human …
Rosejoycrocker Jan 22, 2024
1af510d
Update criteria map plotting method in docs + update example fig
Rosejoycrocker Jan 22, 2024
353032c
Formatting and fix inconsistencies in rebase
Rosejoycrocker Jan 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/src/assets/imgs/criteria_spatial_plots.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions docs/src/usage/analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,35 @@ save("ranks_plot.png", rank_fig)

![Rank frequency plots for multiple ranks](/ADRIA.jl/dev/assets/imgs/ranks_plot.png?raw=true "Rank frequency plot 3 ranks")

## Intervention location selection - plot criteria maps

```julia

dom = ADRIA.load_domain("path to domain", "45")
scens = ADRIA.sample_guided(dom, 8)

mcda_funcs = ADRIA.decision.mcda_methods()

scens = ADRIA.sample_guided(dom, 2^5)
rs = ADRIA.run_scenarios(dom, scens, "45")

# Remove any risk filtering
scens[1, ["deployed_coral_risk_tol"]] .= [1.0]

# Create decision matrices for first scenario, get aggregate score using the
# first MCDA method
decision_dict = ADRIA.decision.decision_matrices(rs, scens[1, :], mcda_funcs[1])

# Plot maps of seeding criteria and aggreagte selection score
fig_criteria = hs = ADRIA.viz.map(
rs, decision_dict[:seed_matrix], decision_dict[:seed_scores]
)
save("criteria_maps.png", fig_criteria)
```

![Spatial maps of location selection criteria](/ADRIA.jl/dev/assets/imgs/criteria_spatial_plots.png?raw=true "Spatial maps of location selection criteria")


### PAWN sensitivity (heatmap overview)

The PAWN sensitivity analysis method is a moment-independent approach to Global Sensitivity
Expand Down
11 changes: 6 additions & 5 deletions ext/AvizExt/viz/location_selection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Plot a spatial map of location selection frequencies.
- `opts` : Aviz options
- `colorbar_label`, label for colorbar. Defaults to "Relative Cover".
- `color_map`, preferred colormap for plotting heatmaps.
- `colorbar_limits` : Upper and lower limits displayed on colorbar,
(default is (0.0, maximum(data)))
- `axis_opts` : Additional options to pass to adjust Axis attributes
See: https://docs.makie.org/v0.19/api/index.html#Axis
- `fig_opts` : Additional options to pass to adjust Figure creation
Expand All @@ -29,7 +31,7 @@ Plot a spatial map of location selection frequencies.
Figure
"""
function ADRIA.viz.ranks_to_frequencies!(
g::Union{GridLayout,GridPosition},
g::Union{GridLayout, GridPosition},
rs::ResultSet,
frequencies::NamedDimsArray,
rank_ids::Vector{Int64};
Expand Down Expand Up @@ -86,7 +88,7 @@ function ADRIA.viz.ranks_to_frequencies!(
return g
end
function ADRIA.viz.ranks_to_frequencies!(
g::Union{GridLayout,GridPosition},
g::Union{GridLayout, GridPosition},
rs::ResultSet,
frequencies::NamedDimsArray,
rank_id::Int64;
Expand All @@ -110,10 +112,9 @@ end
function ADRIA.viz.ranks_to_frequencies(
rs::ResultSet,
frequencies::NamedDimsArray,
rank_ids::Union{Int64,Vector{Int64}};
rank_ids::Union{Int64, Vector{Int64}};
opts::Dict=Dict(),
fig_opts::Dict=Dict(), axis_opts::Dict=Dict())

f = Figure(; fig_opts...)
g = f[1, 1] = GridLayout()
ADRIA.viz.ranks_to_frequencies!(
Expand Down Expand Up @@ -141,7 +142,7 @@ Retrieve set of colormaps for plotting overlayed colormaps.
Maps for each key in rank_groups to a unique colormap.
"""
function _default_colormap(
rank_groups::Dict{Symbol,BitVector}, alpha_vals::Dict{Symbol,Float64}
rank_groups::Dict{Symbol, BitVector}, alpha_vals::Dict{Symbol, Float64}
)
rank_colors = colors(rank_groups, alpha_vals)
rank_ids = keys(rank_groups)
Expand Down
45 changes: 22 additions & 23 deletions ext/AvizExt/viz/scenarios.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ function ADRIA.viz.scenarios(
)
end
function ADRIA.viz.scenarios!(
g::Union{GridLayout,GridPosition},
g::Union{GridLayout, GridPosition},
rs::ResultSet,
outcomes::NamedDimsArray;
opts::Dict=Dict(:by_RCP => false),
axis_opts::Dict=Dict(),
series_opts::Dict=Dict(),
)::Union{GridLayout,GridPosition}
)::Union{GridLayout, GridPosition}
opts[:histogram] = get(opts, :histogram, false)

return ADRIA.viz.scenarios!(
Expand Down Expand Up @@ -91,13 +91,13 @@ function ADRIA.viz.scenarios(
return f
end
function ADRIA.viz.scenarios!(
g::Union{GridLayout,GridPosition},
g::Union{GridLayout, GridPosition},
scenarios::DataFrame,
outcomes::NamedDimsArray;
opts::Dict=Dict(),
axis_opts::Dict=Dict(),
series_opts::Dict=Dict(),
)::Union{GridLayout,GridPosition}
)::Union{GridLayout, GridPosition}
# Ensure last year is always shown in x-axis
xtick_vals = get(axis_opts, :xticks, _time_labels(timesteps(outcomes)))
xtick_rot = get(axis_opts, :xticklabelrotation, 2 / π)
Expand All @@ -121,14 +121,14 @@ function ADRIA.viz.scenarios!(
)
end
function ADRIA.viz.scenarios!(
g::Union{GridLayout,GridPosition},
g::Union{GridLayout, GridPosition},
ax::Axis,
outcomes::NamedDimsArray,
scen_groups::Dict{Symbol,BitVector};
scen_groups::Dict{Symbol, BitVector};
opts::Dict=Dict(),
axis_opts::Dict=Dict(),
series_opts::Dict=Dict(),
)::Union{GridLayout,GridPosition}
)::Union{GridLayout, GridPosition}
if get(opts, :summarize, true)
scenarios_confint!(ax, outcomes, scen_groups)
else
Expand All @@ -149,7 +149,7 @@ function ADRIA.viz.scenarios!(
end

function _confints(
outcomes::NamedDimsArray, scen_groups::Dict{Symbol,BitVector}
outcomes::NamedDimsArray, scen_groups::Dict{Symbol, BitVector}
)::Array{Float64}
groups::Vector{Symbol} = _sort_keys(scen_groups, outcomes)
n_timesteps::Int64 = size(outcomes, 1)
Expand All @@ -171,10 +171,9 @@ function scenarios_confint!(
ax::Axis,
confints::AbstractArray,
ordered_groups::Vector{Symbol},
_colors::Dict{Symbol,Union{Symbol,RGBA{Float32}}};
x_vals::Union{Vector{Int64},Vector{Float64}}=collect(1:size(confints, 1)),
_colors::Dict{Symbol, Union{Symbol, RGBA{Float32}}};
x_vals::Union{Vector{Int64}, Vector{Float64}}=collect(1:size(confints, 1)),
)::Nothing

for idx in eachindex(ordered_groups)
band_color = (_colors[ordered_groups[idx]], 0.4)
y_lower, y_upper = confints[:, idx, 1], confints[:, idx, 3]
Expand All @@ -187,9 +186,9 @@ function scenarios_confint!(
return nothing
end
function scenarios_confint!(
ax::Axis, outcomes::NamedDimsArray, scen_groups::Dict{Symbol,BitVector}
ax::Axis, outcomes::NamedDimsArray, scen_groups::Dict{Symbol, BitVector}
)::Nothing
_colors::Dict{Symbol,Union{Symbol,RGBA{Float32}}} = colors(scen_groups)
_colors::Dict{Symbol, Union{Symbol, RGBA{Float32}}} = colors(scen_groups)
ordered_groups = _sort_keys(scen_groups, outcomes)
confints = _confints(outcomes, scen_groups)
return scenarios_confint!(
Expand All @@ -204,13 +203,13 @@ end
function scenarios_series!(
ax::Axis,
outcomes::NamedDimsArray,
scen_groups::Dict{Symbol,BitVector};
scen_groups::Dict{Symbol, BitVector};
series_opts::Dict=Dict(),
x_vals::Union{Vector{Int64},Vector{Float64}}=collect(1:size(outcomes, 1)),
x_vals::Union{Vector{Int64}, Vector{Float64}}=collect(1:size(outcomes, 1)),
sort_by=:size,
)::Nothing
_colors::Dict{Symbol,Union{Symbol,RGBA{Float32}}} = colors(scen_groups)
_alphas::Dict{Symbol,Float64} = alphas(scen_groups)
_colors::Dict{Symbol, Union{Symbol, RGBA{Float32}}} = colors(scen_groups)
_alphas::Dict{Symbol, Float64} = alphas(scen_groups)

for group in _sort_keys(scen_groups, outcomes; by=sort_by)
color = (_colors[group], _alphas[group])
Expand All @@ -222,9 +221,9 @@ function scenarios_series!(
end

function scenarios_hist(
g::Union{GridLayout,GridPosition},
g::Union{GridLayout, GridPosition},
outcomes::NamedDimsArray,
scen_groups::Dict{<:Any,BitVector},
scen_groups::Dict{<:Any, BitVector},
)::Nothing
scen_dist = dropdims(mean(outcomes; dims=:timesteps); dims=:timesteps)
ax_hist = Axis(g[1, 2]; width=100)
Expand All @@ -248,9 +247,9 @@ function scenarios_hist(
end

function _render_legend(
g::Union{GridLayout,GridPosition},
scen_groups::Dict{<:Any,BitVector},
legend_position::Tuple{Int64,Int64},
g::Union{GridLayout, GridPosition},
scen_groups::Dict{<:Any, BitVector},
legend_position::Tuple{Int64, Int64},
)::Nothing
group_names::Vector{Symbol} = sort(collect(keys(scen_groups)))
_colors = colors(scen_groups)
Expand All @@ -274,7 +273,7 @@ Sort types by variance in reverse order.
- :counterfactual
"""
function _sort_keys(
scenario_types::Dict{Symbol,BitVector},
scenario_types::Dict{Symbol, BitVector},
outcomes::AbstractArray;
by=:variance,
)::Vector{Symbol}
Expand Down
104 changes: 94 additions & 10 deletions ext/AvizExt/viz/spatial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Create a spatial choropleth figure.
- `centroids` : Vector{Tuple}, of lon and lats
- `show_colorbar` : Whether to show a colorbar (true) or not (false)
- `colorbar_label` : Label to use for color bar
- `colorbar_limits` : Upper and lower limits displayed on colorbar,
(default is (0.0, maximum(data)))
- `color_map` : Type of colormap to use,
See: https://docs.makie.org/stable/documentation/colors/#colormaps
- `legend_params` : Legend parameters
Expand All @@ -34,6 +36,7 @@ function create_map!(
centroids::Vector,
show_colorbar::Bool=true,
colorbar_label::String="",
colorbar_limits::Tuple{Float64, Float64}=(0.0, maximum(data)),
color_map::Union{Symbol, Vector{Symbol}, RGBA{Float32}, Vector{RGBA{Float32}}}=:grayC,
legend_params::Union{Tuple, Nothing}=nothing,
axis_opts::Dict=Dict(),
Expand All @@ -58,28 +61,23 @@ function create_map!(

spatial.yticklabelpad = 50
spatial.ytickalign = 10
max_val = @lift(maximum($data))

# Plot geodata polygons using data as internal color
color_range = (0.0, max_val[])

poly!(
spatial,
geodata;
color=data,
colormap=color_map,
colorrange=color_range,
strokecolor=(:black, 0.05),
strokewidth=1.0,
)

if show_colorbar
Colorbar(
f[1, 2];
colorrange=color_range,
colormap=color_map,
label=colorbar_label,
height=Relative(0.65),
limits=colorbar_limits,
)
end

Expand Down Expand Up @@ -126,17 +124,32 @@ function create_map!(
end

"""
ADRIA.viz.map(rs::Union{Domain,ResultSet}; opts=Dict(by_RCP => false), fig_opts=Dict(), axis_opts=Dict(), series_opts=Dict())
ADRIA.viz.map(rs::ResultSet, y::NamedDimsArray; opts=Dict(by_RCP => false), fig_opts=Dict(), axis_opts=Dict(), series_opts=Dict())
ADRIA.viz.map!(f::Union{GridLayout,GridPosition}, rs::ADRIA.ResultSet, y::NamedDimsArray; opts=Dict(by_RCP => false), axis_opts=Dict(), series_opts=Dict())
ADRIA.viz.map(rs::Union{Domain,ResultSet}; opts=Dict(by_RCP => false), fig_opts=Dict(),
axis_opts=Dict(), series_opts=Dict())
ADRIA.viz.map(rs::ResultSet, y::NamedDimsArray; opts=Dict(by_RCP => false), fig_opts=Dict(),
axis_opts=Dict(), series_opts=Dict())
ADRIA.viz.map(rs::ResultSet, S::NamedDimsArray, scores::Vector{Float64};
criteria::Vector{Symbol} = S.criteria, opts::Dict = Dict(), axis_opts::Dict = Dict(),
fig_opts::Dict = Dict())
ADRIA.viz.map!(f::Union{GridLayout,GridPosition}, rs::ADRIA.ResultSet, y::NamedDimsArray;
opts=Dict(by_RCP => false), axis_opts=Dict(), series_opts=Dict())
ADRIA.viz.map!(g::Union{GridLayout,GridPosition},rs::ResultSet, S::NamedDimsArray,
scores::Vector{Float64}; criteria::Vector{Symbol} = S.criteria, opts::Dict = Dict(),
axis_opts::Dict = Dict(), fig_opts::Dict = Dict())

Plot spatial choropleth of outcomes.

# Arguments
- `rs` : ResultSet
- `y` : results of scenario metric
- `S` : A normalised decision matrix calculated using decison.decision_matrices
- `scores` : Aggregated criteria scores.
- `criteria` : Names of criteria to be plotted, if not specified all criteria in
S will be plotted.
- `opts` : Aviz options
- `colorbar_label`, label for colorbar. Defaults to "Relative Cover"
-`colorbar_limits`, min and max values to be shown on the colorbar.
Defaults to (0.0,maximum(y)).
- `color_map`, preferred colormap for plotting heatmaps
- `axis_opts` : Additional options to pass to adjust Axis attributes
See: https://docs.makie.org/v0.19/api/index.html#Axis
Expand Down Expand Up @@ -196,7 +209,7 @@ function ADRIA.viz.map!(
legend_params = get(opts, :legend_params, nothing)
show_colorbar = get(opts, :show_colorbar, true)
color_map = get(opts, :color_map, :grayC)

colorbar_limits = get(opts, :colorbar_limits, (0.0, maximum(y)))
return create_map!(
g,
geodata,
Expand All @@ -205,11 +218,82 @@ function ADRIA.viz.map!(
ADRIA.centroids(rs),
show_colorbar,
c_label,
colorbar_limits,
color_map,
legend_params,
axis_opts,
)
end
function ADRIA.viz.map(
rs::ResultSet,
S::NamedDimsArray,
scores::Vector{Float64};
criteria::Vector{Symbol}=S.criteria,
opts::Dict=Dict(),
axis_opts::Dict=Dict(),
fig_opts::Dict=Dict(),
)
f = Figure(; fig_opts...)
g = f[1, 1] = GridLayout()
ADRIA.viz.map!(
g, rs, S, scores; criteria=criteria, opts=opts, axis_opts=axis_opts
)
return f
end
function ADRIA.viz.map!(
g::Union{GridLayout, GridPosition},
rs::ResultSet,
S::NamedDimsArray,
scores::Vector{Float64};
criteria::Vector{Symbol}=S.criteria,
opts::Dict=Dict(),
axis_opts::Dict=Dict(),
)
if length(rs.site_data.site_id) != size(S, 1)
error("Only unfiltered decision matrices can be plotted.")
end

opts[:color_map] = get(opts, :color_map, :viridis)
opts[:colorbar_limits] = get(opts, :colorbar_limits, (0.0, 1.0))

m_spec = model_spec(rs)
criteria_names::Vector{String} = m_spec[
dropdims(
any(
reshape(criteria, 1, length(criteria)) .== m_spec[:, "fieldname"]; dims=2
);
dims=2,
), "name"]
n_criteria::Int64 = length(criteria)
n_rows, n_cols = _calc_gridsize(n_criteria + 1)
step::Int64 = 1

for row in 1:n_rows, col in 1:n_cols
if step > length(criteria_names)
ADRIA.viz.map!(
g[row, col],
rs,
vec(scores);
opts=opts,
axis_opts=Dict(:title => "Aggregate criteria score"; axis_opts...),
)
break
end
axis_opts_temp = Dict(:title => criteria_names[step]; axis_opts...)
ADRIA.viz.map!(
g[row, col],
rs,
vec(S(criteria[step]));
opts=opts,
axis_opts=axis_opts_temp,
)

step += 1
end

# Clear empty figures
return trim!(g)
end

"""
make_geojson_copy(ds::Union{ResultSet,Domain})::String
Expand Down
Loading