Powered by AppSignal & Oban Pro

Map Animations

11_map_animations.livemd

Map Animations

Mix.install([
  {:plotly_ex, "~> 0.3"},
  {:kino, "~> 0.18"}
])

Section

Animate a choropleth map across time using frames. Each frame has a data entry with updated z values. The map projection stays fixed.

alias Plotly.{Figure, Choropleth}

# Simulated GDP growth data per country across years
countries = ~w[USA GBR DEU FRA JPN CHN IND BRA CAN AUS]
base_gdp = %{
  "USA" => 65000, "GBR" => 42000, "DEU" => 48000, "FRA" => 43000, "JPN" => 40000,
  "CHN" => 12000, "IND" => 7000, "BRA" => 15000, "CAN" => 52000, "AUS" => 55000
}
years = 2015..2022

frames =
  for {year, i} <- Enum.with_index(years) do
    z = Enum.map(countries, fn c -> base_gdp[c] * (1 + i * 0.04) end)
    %{
      name: "#{year}",
      data: [%{z: z, zmin: 5000, zmax: 80000}],
      layout: %{title: %{text: "GDP per Capita — #{year}"}}
    }
  end

slider_steps =
  for year <- years do
    %{
      label: "#{year}",
      method: "animate",
      args: [["#{year}"], %{mode: "immediate", frame: %{duration: 500}, transition: %{duration: 300}}]
    }
  end

Figure.new(
  data: [Choropleth.new(
    locations: countries,
    z: Enum.map(countries, fn c -> base_gdp[c] end),
    locationmode: "ISO-3",
    colorscale: "Blues",
    zmin: 5000,
    zmax: 80000,
    colorbar: %{title: %{text: "GDP/capita"}}
  )],
  layout: %{
    title: "GDP per Capita — 2015",
    geo: %{projection: %{type: "natural earth"}, showland: true, landcolor: "lightgray"},
    sliders: [%{
      steps: slider_steps,
      active: 0,
      currentvalue: %{prefix: "Year: ", visible: true},
      pad: %{t: 50}
    }],
    updatemenus: [%{
      type: "buttons",
      showactive: false,
      y: 0,
      x: 0.5,
      xanchor: "center",
      yanchor: "top",
      pad: %{t: 60},
      buttons: [%{
        label: "▶ Play",
        method: "animate",
        args: [nil, %{frame: %{duration: 600}, transition: %{duration: 300}, fromcurrent: true}]
      }]
    }]
  },
  frames: frames
)
|> Plotly.show()