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

Improvement of the visualization code #68

Merged
merged 11 commits into from
Feb 2, 2024
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ TimeseriesSurrogates = "c804724b-8c18-5caa-8579-6025a0767c70"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"

[extensions]
TITVisualizations = "Makie"
TransitionVisualizations = "Makie"

[compat]
DelimitedFiles = "1"
Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ bib = CitationBibliography(joinpath(@__DIR__, "src", "refs.bib"); style=:authory

build_docs_with_style(pages, TransitionsInTimeseries, StatsBase;
authors = "Jan Swierczek-Jereczek <[email protected]>, "*
"George Datseris <[email protected]>", warnonly = true, bib)
"George Datseris <[email protected]>", bib)
16 changes: 16 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ ar1_whitenoise

```@docs
LowfreqPowerSpectrum
PrecomputedLowfreqPowerSpectrum
```

### Nonlinear dynamics
Expand All @@ -68,6 +69,7 @@ and giving the created `indicator` to e.g., [`SlidingWindowConfig`](@ref).
kendalltau
spearman
RidgeRegressionSlope
PrecomputedRidgeRegressionSlope
```

### Value distribution differences
Expand Down Expand Up @@ -103,3 +105,17 @@ windowmap!
```@docs
load_linear_vs_doublewell()
```

## Visualization

```@docs
plot_indicator_changes
plot_significance!
plot_changes_significance
```

## Utils

```docs
default_window_width
```
60 changes: 32 additions & 28 deletions docs/src/tutorial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

# Tutorial

## [Workflow](@id workflow)
## [Workflow] (@id workflow)

Computing transition indicators consists of the following steps:

1. Doing any preprocessing of raw data first, such as detrending (_not part of TransitionsInTimeseries.jl_). This yields the **input timeseries**.
1. Doing any preprocessing of raw data first, such as detrending. _This not part of TransitionsInTimeseries.jl_ and yields the **input timeseries**.
Datseris marked this conversation as resolved.
Show resolved Hide resolved
2. Estimating the timeseries of an indicator by sliding a window over the input timeseries.
3. Computing the changes of the indicator by sliding a window over its timeseries.
3. Computing the changes of the indicator by sliding a window over its timeseries. Alternatively, the change metric can be estimated over the whole segment, as examplified in the section [Segmented windows](@ref segmented_windows).
4. Generating many surrogates that preserve important statistical properties of the original timeseries.
5. Performing step 2 and 3 for the surrogate timeseries.
6. Checking whether the indicator change timeseries of the real timeseries shows a significant feature (trend, jump or anything else) when compared to the surrogate data.
Expand Down Expand Up @@ -185,7 +185,9 @@ Performing the step-by-step analysis of transition indicators is possible and mi

TransitionsInTimeseries.jl wraps this typical workflow into a simple, extendable, and modular API that researchers can use with little effort. In addition, it allows performing the same analysis for several indicators / change metrics in one go.

The interface is simple, and directly parallelizes the [Workflow](@ref).
The interface is simple, and directly parallelizes the [Workflow](@ref workflow). It is based on the creation of a [`IndicatorsChangesConfig`](@ref), which contains a list of indicators, and corresponding metrics, to use for doing the above analysis. It also specifies what kind of surrogates to generate.

### Sliding windows

The following blocks illustrate how the above extensive example is re-created in TransitionsInTimeseries.jl
=#
Expand Down Expand Up @@ -223,41 +225,43 @@ config = SlidingWindowConfig(indicators, change_metrics;
results = estimate_indicator_changes(config, input, t)

#=
From `result` we can plot the change metric timeseries:
We can conveniently plot the information contained in `results` by using
`plot_indicator_changes`:
=#

fig, axs = gridfig(3, 1)
lines!(axs[1], t, input; label = "input", color = Cycled(2))
scatter!(axs[2], results.t_change, results.x_change[:, 1];
label = "var slopes", color = Cycled(3))
scatter!(axs[3], results.t_change, results.x_change[:, 2];
label = "ar1 slopes", color = Cycled(4))
[xlims!(ax, 0, 50) for ax in axs]
fig
tv = plot_indicator_changes(results, additional_timeseries = x_nlinear[2:end])
tv.fig

#=
Step 2 is to estimate significance using [`SurrogatesSignificance`](@ref)
and the function [`significant_transitions`](@ref).
and the function [`significant_transitions`](@ref). Finally, we can
conveniently plot the results obtained by updating the figure obtained
above with `plot_significance!`:
=#

signif = SurrogatesSignificance(n = 1000, tail = [:right, :right])
flags = significant_transitions(results, signif)
plot_significance!(tv, signif, flags = flags)
tv.fig

#=
We can now plot the p-values corresponding to each time series of the change metrics. From the `flags` we can additionally obtain the time points where _both_ indicators show significance, via a simple reduction:
### [Segmented windows] (@id segmented_windows)

The analysis shown so far relies on sliding windows of the change metric.
This is particularly convenient for transition detection tasks. Segmented
windows for the change metric computation are however preferable when it
comes to prediction tasks. By only slightly modifying the syntax used so far,
one can perform the same computations on segmented windows, as well as
visualise the results conveniently:
=#

fig, axs = gridfig(2, 1)
lines!(axs[1], vcat(0.0, t), x_nlinear; label = "raw", color = Cycled(1))
lines!(axs[1], t, input; label = "input", color = Cycled(2))
scatter!(axs[2], results.t_change, signif.pvalues[:, 1];
label = "var p-values", color = Cycled(3))
scatter!(axs[2], results.t_change, signif.pvalues[:, 2];
label = "ar1 p-values", color = Cycled(4))

flagsboth = vec(reduce(&, flags; dims = 2))
vlines!(axs[1], results.t_change[flagsboth]; label = "flags", color = ("black", 0.1))
config = SegmentedWindowConfig(indicators, change_metrics,
t[1:1], t[1200:1200]; whichtime = last, width_ind = 200,
min_width_cha = 100)
results = estimate_indicator_changes(config, input, t)
signif = SurrogatesSignificance(n = 1000, tail = [:right, :right])
flags = significant_transitions(results, signif)
tv = plot_changes_significance(results, signif,
additional_timeseries = x_nlinear[2:end])
tv.fig

[axislegend(ax) for ax in axs]
[xlims!(ax, 0, 50) for ax in axs]
fig
61 changes: 32 additions & 29 deletions docs/src/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ EditURL = "tutorial.jl"

# Tutorial

## [Workflow](@id workflow)
## [Workflow] (@id workflow)

Computing transition indicators consists of the following steps:

1. Doing any preprocessing of raw data first, such as detrending (_not part of TransitionsInTimeseries.jl_). This yields the **input timeseries**.
1. Doing any preprocessing of raw data first, such as detrending. _This not part of TransitionsInTimeseries.jl_ and yields the **input timeseries**.
2. Estimating the timeseries of an indicator by sliding a window over the input timeseries.
3. Computing the changes of the indicator by sliding a window over its timeseries.
3. Computing the changes of the indicator by sliding a window over its timeseries. Alternatively, the change metric can be estimated over the whole segment, as examplified in the section [Segmented windows](@ref segmented_windows).
4. Generating many surrogates that preserve important statistical properties of the original timeseries.
5. Performing step 2 and 3 for the surrogate timeseries.
6. Checking whether the indicator change timeseries of the real timeseries shows a significant feature (trend, jump or anything else) when compared to the surrogate data.
Expand Down Expand Up @@ -187,7 +187,9 @@ Performing the step-by-step analysis of transition indicators is possible and mi

TransitionsInTimeseries.jl wraps this typical workflow into a simple, extendable, and modular API that researchers can use with little effort. In addition, it allows performing the same analysis for several indicators / change metrics in one go.

The interface is simple, and directly parallelizes the [Workflow](@ref). It is based on the creation of a [`SurrogatesSignificance`](@ref), which contains a list of indicators, and corresponding metrics, to use for doing the above analysis. It also specifies what kind of surrogates to generate.
The interface is simple, and directly parallelizes the [Workflow](@ref workflow). It is based on the creation of a [`IndicatorsChangesConfig`](@ref), which contains a list of indicators, and corresponding metrics, to use for doing the above analysis. It also specifies what kind of surrogates to generate.

### Sliding windows

The following blocks illustrate how the above extensive example is re-created in TransitionsInTimeseries.jl

Expand Down Expand Up @@ -225,43 +227,44 @@ config = SlidingWindowConfig(indicators, change_metrics;
results = estimate_indicator_changes(config, input, t)
````

From `result` we can plot the change metric timeseries:
We can conveniently plot the information contained in `results` by using
`plot_indicator_changes`:

````@example tutorial
fig, axs = gridfig(3, 1)
lines!(axs[1], t, input; label = "input", color = Cycled(2))
scatter!(axs[2], results.t_change, results.x_change[:, 1];
label = "var slopes", color = Cycled(3))
scatter!(axs[3], results.t_change, results.x_change[:, 2];
label = "ar1 slopes", color = Cycled(4))
[xlims!(ax, 0, 50) for ax in axs]
fig
tv = plot_indicator_changes(results, additional_timeseries = x_nlinear[2:end])
tv.fig
````

Step 2 is to estimate significance using [`SurrogatesSignificance`](@ref)
and the function [`significant_transitions`](@ref).
and the function [`significant_transitions`](@ref). Finally, we can
conveniently plot the results obtained by updating the figure obtained
above with `plot_significance!`:

````@example tutorial
signif = SurrogatesSignificance(n = 1000, tail = [:right, :right])
flags = significant_transitions(results, signif)
plot_significance!(tv, signif, flags = flags)
tv.fig
````

We can now plot the p-values corresponding to each time series of the change metrics. From the `flags` we can additionally obtain the time points where _both_ indicators show significance, via a simple reduction:

````@example tutorial
fig, axs = gridfig(2, 1)
lines!(axs[1], vcat(0.0, t), x_nlinear; label = "raw", color = Cycled(1))
lines!(axs[1], t, input; label = "input", color = Cycled(2))
scatter!(axs[2], results.t_change, signif.pvalues[:, 1];
label = "var p-values", color = Cycled(3))
scatter!(axs[2], results.t_change, signif.pvalues[:, 2];
label = "ar1 p-values", color = Cycled(4))
### [Segmented windows] (@id segmented_windows)

flagsboth = vec(reduce(&, flags; dims = 2))
vlines!(axs[1], results.t_change[flagsboth]; label = "flags", color = ("black", 0.1))
The analysis shown so far relies on sliding windows of the change metric.
This is particularly convenient for transition detection tasks. Segmented
windows for the change metric computation are however preferable when it
comes to prediction tasks. By only slightly modifying the syntax used so far,
one can perform the same computations on segmented windows, as well as
visualise the results conveniently:

[axislegend(ax) for ax in axs]
[xlims!(ax, 0, 50) for ax in axs]
fig
````@example tutorial
config = SegmentedWindowConfig(indicators, change_metrics,
t[1:1], t[1200:1200]; whichtime = last, width_ind = 200,
min_width_cha = 100)
results = estimate_indicator_changes(config, input, t)
signif = SurrogatesSignificance(n = 1000, tail = [:right, :right])
flags = significant_transitions(results, signif)
tv = plot_changes_significance(results, signif,
additional_timeseries = x_nlinear[2:end])
tv.fig
````

69 changes: 0 additions & 69 deletions ext/TITVisualizations.jl

This file was deleted.

Loading
Loading