JuliaDynamics / Attractors.jl

Find attractors of dynamical systems, their basins, and continue them across parameters. Study global stability (a.k.a. non-local, or resilience). Also tipping points functionality.
MIT License
27 stars 5 forks source link

Basins heatmap with a shading proportional to a matrix #120

Closed awage closed 5 months ago

awage commented 5 months ago

This PR brings a new function to produce shading effects in basins.

It has a custom colormap that goes from light to dark colors according to an iteration matrix. The iterations of the mapper are stored with the new get_iterations function. It uses some internal variables of the mapper.

The effect are these gorgeous figures:

Captura de pantalla_2024-01-16_15-00-52 Captura de pantalla_2024-01-16_15-01-57

Test script:

using CairoMakie
using Attractors, StaticArrays
function henon_rule(u, p, n) 
    x, y = u
    a, b = p
    xn = 1.0 - a*x^2 + y
    yn = b*x
    return SVector(xn, yn)
end
u0 = [0.2, 0.3];
p0 = [1.2, 0.3];
henon = DeterministicIteratedMap(henon_rule, u0, p0);
xg = range(-2.5, 2.5; length = 1500)
yg = range(-2.5, 2.5; length = 1500)
grid=(xg,yg)
mapper = AttractorsViaRecurrences(henon, grid; sparse = false)
# basins, attractors = basins_of_attraction(mapper; show_progress = false)
basins = zeros(Int8, 1500, 1500); iterations = zeros(Int32,1500,1500)
for (i,x) in enumerate(xg), (j,y) in enumerate(yg) 
    l = mapper([x,y])
    n = get_iterations(mapper)
    basins[i,j] = l
    iterations[i,j] = n
end
using StatsBase:median
attractors = extract_attractors(mapper)
# Display basins with shading. 
shaded_basins_heatmap(grid, basins, iterations, attractors;  show_attractors = false, maxit = 2*median(iterations), title = "test" )
awage commented 5 months ago

I left some comments in the code on how the gradient is constructed:

    # The colormap is constructed in such a way that the first color maps 
    # from id to id+0.99, id is an integer describing the current basin.
    # Each id has a specific color associated and the gradient goes from 
    # light color (value id) to dark color (value id+0.99). It produces
    # a shading proportional to a value associated to a specific pixel. 

There is some code redundancy between heatmap_attractors and this plotting method. I don't know if it is worth factorizing the two functions.

The colors are also differents. I used named colors from Colors.jl. It is more convenient.

codecov-commenter commented 5 months ago

Codecov Report

Attention: 2 lines in your changes are missing coverage. Please review.

Comparison is base (60b8a6f) 84.85% compared to head (fdb3219) 84.89%.

Files Patch % Lines
src/basins/basins_utilities.jl 93.33% 1 Missing :warning:
...pping/recurrences/attractor_mapping_recurrences.jl 0.00% 1 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #120 +/- ## ========================================== + Coverage 84.85% 84.89% +0.04% ========================================== Files 24 24 Lines 1294 1311 +17 ========================================== + Hits 1098 1113 +15 - Misses 196 198 +2 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

awage commented 5 months ago

Classic DS color scheme: Captura de pantalla_2024-01-22_22-09-43

awage commented 5 months ago

Works for more attractors: Captura de pantalla_2024-01-22_22-23-53

awage commented 5 months ago

Do we need to include the test example? Or just for the docs?

using CairoMakie
using Attractors
using PredefinedDynamicalSystems

ds = Systems.henon([0.2, 0.3]; a = 1.2, b = 0.3)
xg = yg =  range(-2.5, 2.5; length = 1500)
grid=(xg,yg)
mapper = AttractorsViaRecurrences(ds, grid; sparse = false)
basins,attractors, iterations = iterates_of_basins_of_attraction(mapper, grid)

using StatsBase:median
# Display basins with shading. 
shaded_basins_heatmap(grid, basins, iterations, attractors;  show_attractors = true, maxit = 2*median(iterations), title = "test" )
awage commented 5 months ago

Almost finished. The function iterates_of_basins_of_attraction should work on any grid. But the plot is only possible in 2D.

Datseris commented 5 months ago

@awage thanks, I just re-arranged the docs. Since this PR adds and exports a new public function iterates_of_basins_of_attraction, this function also needs to be tested in the test suite. Would you mind writting a quick test please?

Datseris commented 5 months ago

Hm, even though we fixed documentation build in a different PR, in this one it fails, perhaps you need to update this PR with current main?

awage commented 5 months ago

Ok, I will merge main into this branch.

Datseris commented 5 months ago

@awage can you please add the line using OrdinaryDiffEq: Vern9 in the file src/examples.md:882-893 just before the line function fitzhugh_nagumo(u,p,t) ? this is causing the doc failutre (which is unrteated with your PR, it was a mistake from the PR #61 )

awage commented 5 months ago

Done! Lets see if it pass the tests.

Datseris commented 5 months ago

I'll fix and merge this now quickly