Dataslope logoDataslope

Geographic Visualization

Putting data on a map — choropleths, scatter geos, and the things to watch out for

When your data has a location column — country, state, city, zip code, or latitude/longitude — a map is often the right chart. Maps have an enormous advantage: the audience already knows the geography, so you can spend your visual encoding entirely on the data rather than on the layout.

Plotly Express offers three main map families:

  • Choropleths — colored regions (country, state, county).
  • Scatter geospoints on a world map (one dot per location).
  • Mapbox / Density mapbox — tile-based maps with finer geographic detail (cities, addresses).

Choropleths: data per region

A choropleth colors each region (country, state, county) by a data value. It's the standard for "data by country" or "data by state."

Code Block
Python 3.13.2

Hover over countries to read values; zoom and pan to focus on regions. The chart uses about one line of Python plus a built-in country atlas.

locations must contain values Plotly knows how to look up. Common identifier types:

  • "iso_alpha" — three-letter ISO country codes (USA, FRA, JPN).
  • "USA-states" — two-letter US state codes.
  • "country names" — full English names.

For other geographies (counties, custom regions), you supply a GeoJSON file via geojson=....

Scatter geos: data per point

When your data is point-based (cities, observations, individual events), use px.scatter_geo:

Code Block
Python 3.13.2

Each country is a dot (centroid) sized by population. Try different projections: "orthographic", "natural earth", "mercator", "equirectangular".

Map projections — they all lie a little

A map projection is the mathematical rule for flattening a sphere onto a flat page. Every projection distorts something — area, shape, distance, or direction. There is no neutral choice.

  • "natural earth" — Good general-purpose default. Decent balance of shape and area.
  • "orthographic" — Shows the Earth as if from space. Beautiful but only half the globe visible at a time.
  • "equirectangular" (default) — Rectangular grid. Easy to read but stretches polar regions enormously.
  • "mercator" — Made famous by Google Maps. Massively exaggerates the size of regions near the poles (Greenland looks the same size as Africa, but Africa is 14× bigger).

Mercator distortion is a real visualization problem

The Mercator projection famously makes Greenland look as large as Africa, even though Africa is ~14× larger by area. If your map's story depends on area comparisons across latitudes, do not use Mercator. Use "equal-earth" or "natural earth" instead.

Tile-based maps with Mapbox

For cities, addresses, or fine geographic detail, use px.scatter_mapbox or px.density_mapbox. These use map tiles (satellite imagery, OpenStreetMap, etc.) underneath:

fig = px.scatter_mapbox(
    df, lat="latitude", lon="longitude", color="...", size="...",
    mapbox_style="open-street-map",
    zoom=10, height=600,
    template="simple_white",
)

The "open-street-map" style is free; other styles need a Mapbox access token. (For browser-based learning we'll stop here; the choropleth and scatter_geo cover most beginner needs.)

Pitfalls of map visualizations

  • Population bias. A choropleth of "raw counts" almost always just looks like a population map. Normalize to per capita or per area.
  • Visual area dominance. Russia and Canada take up enormous visual space; tiny countries like Singapore disappear. Consider cartograms or a table-augmented map when small regions matter.
  • Color scale matters. Sequential for one-sided data; diverging for two-sided (e.g., year-over-year change).
  • Missing data. Countries you don't have data for will appear uncolored or with a default fill — make sure that doesn't read as "value = 0."

A diverging-color choropleth

A great use case: showing change (positive vs negative) across regions.

Code Block
Python 3.13.2

Every country with declining life expectancy will be red; every gain will be blue. The diverging palette centered at zero makes the story instant.

Check your understanding

QuestionSelect one

A choropleth is best for visualizing:

Trends over time.

Two-variable correlation.

A numeric value per region (country, state, county), encoded as the region's fill color.

A part-of-a-whole composition.

QuestionSelect one

Why is a choropleth of raw counts (e.g., "total COVID cases by country") often misleading?

It uses too much color.

It compresses the data.

The map ends up looking like a population map — big, populous countries always look "darkest" regardless of the per-capita reality.

Choropleths don't support hover.

QuestionSelect one

The Mercator projection famously makes which continent appear roughly the same size as Africa, even though Africa is ~14× larger?

Antarctica.

South America.

Greenland.

Australia.

QuestionSelect one

For a choropleth showing year-over-year change (which can be positive or negative), which color scale is most appropriate?

A qualitative palette like Plotly.

A sequential palette like Viridis.

A diverging palette centered at 0, such as RdBu with color_continuous_midpoint=0.

A grayscale ramp.

On this page