Skip to content

Greenland ice loss example: animated & interactive

julia
using Tyler
using Tyler.TileProviders
using Tyler.Extents
using Dates
using HTTP
using Arrow
using DataFrames
using GLMakie
using GLMakie.Colors
GLMakie.activate!()

INFO

Ice loss from the Greenland Ice Sheet: 1972-2022.

  • Contact person: Alex Gardner & Chad Greene

Load ice loss data [courtesy of Chad Greene @ JPL]

julia
url = "https://github.com/JuliaGeo/JuliaGeoData/blob/365a09596bfca59e0977c20c2c2f566c0b29dbaa/assets/data/iceloss_subset.arrow?raw=true";
resp = HTTP.get(url);
df = DataFrame(Arrow.Table(resp.body));
first(df, 5)

select map provider

julia
provider = TileProviders.Esri(:WorldImagery);
┌ Warning: Error while fetching tile on thread 1
│   exception =
│    RequestError: Connection timed out after 5294 milliseconds while requesting https://tile.opentopomap.org/9/255/170.png
│    Stacktrace:
│      [1] (::Downloads.var"#9#19"{IOBuffer, Base.DevNull, Nothing, Vector{Pair{String, String}}, Float64, Nothing, Bool, Nothing, Bool, Nothing, String, Bool, Bool})(easy::Downloads.Curl.Easy)
│        @ Downloads /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:452
│      [2] with_handle(f::Downloads.var"#9#19"{IOBuffer, Base.DevNull, Nothing, Vector{Pair{String, String}}, Float64, Nothing, Bool, Nothing, Bool, Nothing, String, Bool, Bool}, handle::Downloads.Curl.Easy)
│        @ Downloads.Curl /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Curl/Curl.jl:105
│      [3] #8
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:363 [inlined]
│      [4] arg_write(f::Downloads.var"#8#18"{Base.DevNull, Nothing, Vector{Pair{String, String}}, Float64, Nothing, Bool, Nothing, Bool, Nothing, String, Bool, Bool}, arg::IOBuffer)
│        @ ArgTools /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/ArgTools/src/ArgTools.jl:134
│      [5] #7
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:362 [inlined]
│      [6] arg_read
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/ArgTools/src/ArgTools.jl:76 [inlined]
│      [7] request(url::String; input::Nothing, output::IOBuffer, method::Nothing, headers::Vector{Pair{String, String}}, timeout::Float64, progress::Nothing, verbose::Bool, debug::Nothing, throw::Bool, downloader::Downloads.Downloader, interrupt::Nothing)
│        @ Downloads /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:361
│      [8] request
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:328 [inlined]
│      [9] #3
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:259 [inlined]
│     [10] arg_write(f::Downloads.var"#3#4"{Nothing, Vector{Pair{String, String}}, Float64, Nothing, Bool, Nothing, Downloads.Downloader, String}, arg::IOBuffer)
│        @ ArgTools /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/ArgTools/src/ArgTools.jl:134
│     [11] #download#2
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:258 [inlined]
│     [12] download
│        @ /opt/hostedtoolcache/julia/1.11.2/x64/share/julia/stdlib/v1.11/Downloads/src/Downloads.jl:247 [inlined]
│     [13] download_tile_data(dl::Tyler.ByteDownloader, provider::TileProviders.Provider, url::String)
│        @ Tyler ~/work/Tyler.jl/Tyler.jl/src/downloader.jl:19
│     [14] fetch_tile
│        @ ~/work/Tyler.jl/Tyler.jl/src/provider/shared.jl:10 [inlined]
│     [15] (::Tyler.var"#20#21"{Tyler.ByteDownloader, TileProviders.Provider, MapTiles.Tile})()
│        @ Tyler ~/work/Tyler.jl/Tyler.jl/src/tile-cache.jl:93
│     [16] get!(default::Tyler.var"#20#21"{Tyler.ByteDownloader, TileProviders.Provider, MapTiles.Tile}, lru::LRUCache.LRU{String, Union{Nothing, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}}}, key::String)
│        @ LRUCache ~/.julia/packages/LRUCache/ctUcD/src/LRUCache.jl:169
│     [17] run_loop(dl::Tyler.ByteDownloader, tile_queue::Channel{MapTiles.Tile}, fetched_tiles::LRUCache.LRU{String, Union{Nothing, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}}}, provider::TileProviders.Provider, downloaded_tiles::Channel{Tuple{MapTiles.Tile, Union{Nothing, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}}}})
│        @ Tyler ~/work/Tyler.jl/Tyler.jl/src/tile-cache.jl:91
│     [18] (::Tyler.var"#8#11"{TileProviders.Provider, Channel{MapTiles.Tile}, Channel{Tuple{MapTiles.Tile, Union{Nothing, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}}}}, LRUCache.LRU{String, Union{Nothing, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}}}, Tyler.ByteDownloader})()
│        @ Tyler ~/work/Tyler.jl/Tyler.jl/src/tile-cache.jl:27
└ @ Tyler ~/work/Tyler.jl/Tyler.jl/src/tile-cache.jl:106

Greenland extent

julia
extent = Extent(X = (-54., -48.), Y = (68.8, 72.5));
Extent(X = (-54.0, -48.0), Y = (68.8, 72.5))

extract data

julia
cnt = [length(foo) for foo in df.X];
X =  reduce(vcat,df.X);
Y =  reduce(vcat,df.Y);
Z = [repeat([i],c) for (i, c) = enumerate(cnt)];
Z = reduce(vcat,Z);

make a colormap

julia
nc = length(Makie.to_colormap(:thermal));
n = nrow(df);
alpha = zeros(nc);
alpha[1:maximum([1,round(Int64,1*nc/n)])] = alpha[1:maximum([1,round(Int64,1*nc/n)])] .* (1.05^-1.5);
alpha[maximum([1,round(Int64,1*nc/n)])] = 1;
cmap = Colors.alphacolor.(Makie.to_colormap(:thermal), alpha);
cmap = Observable(cmap);

show map

julia
fig = Figure(; size = (1200,600))
ax = Axis(fig[1,1])
m = Tyler.Map(extent; provider, figure=fig, axis=ax)

create initial scatter plot

julia
scatter!(ax, X, Y; color = Z, colormap = cmap, colorrange = [0, n], markersize = 10);
m

add colorbar

julia
a,b = extrema(df.Date);
a = year(a);
b = year(b);
Colorbar(fig[1,2]; colormap = cmap, colorrange = [a,b],
    height=Relative(0.5), width = 15)
# hide ticks, grid and lables
hidedecorations!(ax);
# hide frames
hidespines!(ax);
m

loop to create animation

julia
for k = 1:15
    # reset apha
    alpha[:] = zeros(nc);
    cmap[] = Colors.alphacolor.(cmap[], alpha)
    for i in 2:1:n
        # modify alpha
        alpha[1:maximum([1,round(Int64,i*nc/n)])] = alpha[1:maximum([1,round(Int64,i*nc/n)])] .* (1.05^-1.5);
        alpha[maximum([1,round(Int64,i*nc/n)])] = 1;
        cmap[] = Colors.alphacolor.(cmap[], alpha);
        sleep(0.001);
    end
end