🏠 back to Observable

Setting null value to a default colour on choropleth map

Hi

Use case: @ashwinjm/introducing-maps

vl.markGeoshape({stroke: "black"}).config({invalidValues: null})
  .data(vl.topojson(countries_url).feature("countries1"))
  .transform(vl.lookup("id").from(vl.data(ag_data).key("Country Code").fields("2015")))
  .encode(vl.color().fieldQ("2015").condition({test: "datum['2015'] == null", value: "lightgrey"}),
          vl.tooltip("properties.name"))
  .height(500)
  .width(700)
  .render()

This map is supposed to fix the missing area with the code snippet condition({test: "datum['2015'] == null", value: "lightgrey"}) but it doesn’t seem to work, and I can’t get mine to work either. Is there something wrong/outdated here or am I missing something?

My example: @indiebio/global-innovation-index

Thanks

I think that when encoding geoshapes they are only drawn if the encoding is valid. You can get what you want by creating a two layer map - one for the background and one for the colour-encoded shapes. Those null-encoded shapes won’t get drawn so leaving the background ‘underneath’. For example:

vl
  .layer(
    // Background layer
    vl
      .markGeoshape({ fill: "lightgrey" })
      .data(vl.topojson(world).feature("countries1"))
      .project(vl.projection("equalEarth")),

    // Choropleth layer
    vl
      .markGeoshape({ stroke: "lightgrey" })
      .data(vl.topojson(world).feature("countries1"))
      .transform(
        vl
          .lookup("id")
          .from(
            vl.data(selectIndex).key("ID").fields("RankingScore", "Ranking")
          )
      )
      .encode(
        vl
          .color()
          .fieldQ("RankingScore")
          .scale({ opacity: 0.9, domain: [0, 100], clamp: true })
      )
  )
  .render()

(as an aside – you may find better projections than the Mercator for this kind of mapping. “EqualEarth” does a good job of balancing equal area projection with not too much shape distortion. No more devoting half the map space to northern Canada and Antarctica)

1 Like

Thank you, that makes sense. Ideally having the name still pop up with a “0” or “no data” would be good, but this is already good enough to export to a report. I did try to ensure the encoding of the ID field is valid (with the three-letter international codes to prevent naming differences) but it didn’t work, and also didn’t work in ashwinjm’s example.

Re mercator, thank you! I had that on my todo list and then got distracted before I could find a better one :slight_smile: Decided to go with Equirectangular, and might reload the world map without Antartica…