Skip to content

Commit

Permalink
improve handling of impossible ylimits for axes (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
Datseris committed May 24, 2024
1 parent 851657d commit 19f7e3e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DynamicalSystems"
uuid = "61744808-ddfa-5f27-97ff-6e42cc95d634"
repo = "https://github.com/JuliaDynamics/DynamicalSystems.jl.git"
version = "3.3.14"
version = "3.3.15"

[deps]
Attractors = "f3fd9213-ca85-4dba-9dfd-7fc91308fec7"
Expand Down
24 changes: 19 additions & 5 deletions ext/src/interactive_trajectory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ function _trajectory_plot_controls!(gl, statespace_axis::Bool, starting_step)
)
return reset.clicks, run.clicks, step.clicks, sg.sliders[1].value
end

function _traj_lim_estimator(ds, u0s, idxs, observables, dt)
ds = deepcopy(ds)
mi = fill(Inf, length(idxs))
Expand All @@ -226,21 +227,24 @@ function _traj_lim_estimator(ds, u0s, idxs, observables, dt)
tr, = DynamicalSystems.trajectory(ds, 1000dt, u0s[i]; Δt = dt)
_tr = StateSpaceSet(map(u -> [observe_state(ds, i, u) for i in idxs], tr))
mii, maa = DynamicalSystems.minmaxima(_tr)
mi = min.(mii, mi)
ma = max.(maa, ma)
mi = isnumber(mii) ? min.(mii, mi) : mi
ma = isnumber(maa) ? max.(maa, ma) : ma
# do same but now by transforming the `tr` set into the observed set
otr = map(u -> Float64[observe_state(ds, f, u) for f in observables], tr)
otr = StateSpaceSet(otr)
omii, omaa = DynamicalSystems.minmaxima(otr)
omi = min.(omii, omi)
oma = max.(omaa, oma)
omi = isnumber(omii) ? min.(omii, omi) : omi
oma = isnumber(omaa) ? max.(omaa, oma) : oma
end
# Alright, now we just have to put them into limits and increase a bit
lims = [(mi[i]-0.02mi[i], ma[i]+0.02ma[i]) for i in 1:length(idxs)]
lims = (lims...,)
observable_lims = [(omi[i]-0.02omi[i], oma[i]+0.02oma[i]) for i in 1:length(observables)]
return lims, observable_lims
end
# we use this function because min/max is contaminated by NaN/Infs
isnumber(x::Real) = !(isnan(x) || isinf(x))
isnumber(x) = all(isnumber, x)

# Parameter handling
function _add_ds_param_controls!(ds, paramlayout, parameter_sliders, pnames, p0)
Expand Down Expand Up @@ -307,7 +311,17 @@ function _init_timeseries_plots!(

# First, create axis
axs = [Axis(layout[i, 1]; ylabel = tsnames[i]) for i in 1:length(fs)]
for i in 1:length(fs); ylims!(axs[i], tslims[i]); end
for i in 1:length(fs);
# we use a `try` clause here because there may be cases
# where the ylims are the same, such as 0-0. NaNs we already take care of in the automatic estimator!
try
ylims!(axs[i], tslims[i])
catch err
@warn "Couldn't automatically set axis y-limits for observable $(fs[i]). "*
"Got error: $(err)"
end
end

linkxaxes!(axs...)
for i in 1:length(fs)-1; hidexdecorations!(axs[i]; grid = false); end
axs[end].xlabel = timelabel
Expand Down

0 comments on commit 19f7e3e

Please sign in to comment.