Powered by AppSignal & Oban Pro

Tile County Choropleth — Basic Tile

29_tile_county_choropleth_basic.livemd

Tile County Choropleth — Basic Tile

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

Section

Choroplethmap is the tile-map equivalent of Choropleth. It requires a geojson: map with feature boundaries and featureidkey: to match GeoJSON features to locations: values. Unlike Choropleth, it renders on a tile base map (layout.map) instead of a geo projection.

alias Plotly.{Figure, Choroplethmap}

# Fetch US county GeoJSON (filter to one state for performance)
geojson_url = "https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json"
geojson = Req.get!(geojson_url).body |> Jason.decode!()

# Filter to California (FIPS codes starting with "06")
ca_geojson = Map.update!(geojson, "features", fn features ->
  Enum.filter(features, fn f -> String.starts_with?(f["id"], "06") end)
end)

# Fetch unemployment data
data_url = "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv"
body = Req.get!(data_url).body

[header | rows] = String.split(body, "\n", trim: true)
keys = String.split(header, ",") |> Enum.map(&String.trim/1)

data =
  rows
  |> Enum.map(fn row ->
    values = String.split(row, ",")
    Enum.zip(keys, values) |> Map.new()
  end)
  |> Enum.filter(fn r ->
    r["fips"] != nil and r["fips"] != "" and String.starts_with?(String.pad_leading(r["fips"], 5, "0"), "06")
  end)

fips = Enum.map(data, fn r -> String.pad_leading(r["fips"], 5, "0") end)
unemp = Enum.map(data, fn r ->
  case Float.parse(r["unemp"]) do
    {f, _} -> f
    :error -> 0.0
  end
end)

Figure.new()
|> Figure.add_trace(
  Choroplethmap.new(
    geojson: ca_geojson,
    locations: fips,
    z: unemp,
    featureidkey: "id",
    colorscale: "Viridis",
    zmin: 0,
    zmax: 12,
    colorbar: %{title: %{text: "Unemployment %"}}
  )
)
|> Figure.update_layout(
  title: "California County Unemployment — Basic Tile",
  map: %{
    style: "carto-positron",
    center: %{lat: 37.5, lon: -120.0},
    zoom: 5
  }
)
|> Plotly.show()