Atlas

Introduction

Cartes comes with a facilitated access to repositories of topojson files online. topojson is a very lightweight format compared to geojson, so it is excellent for transferring files over the Internet, and for a direct integration in Altair.

Currently we have two major repositories for maps:

name

repository

type

default

https://github.com/deldersveld/topojson

Github

world_atlas

https://cdn.jsdelivr.net/npm/world-atlas@2/

npm

The list of maps available in each repository is available with each module:

from cartes.atlas import default

default
path download_url type size
2 USARegion.json https://raw.githubusercontent.com/xoolive/topo... file 856363
6 world-continents.json https://raw.githubusercontent.com/xoolive/topo... file 72125
7 world-countries-sans-antarctica.json https://raw.githubusercontent.com/xoolive/topo... file 109244
8 world-countries.json https://raw.githubusercontent.com/xoolive/topo... file 115340
9 continents/africa.json https://raw.githubusercontent.com/xoolive/topo... file 17730
... ... ... ... ...
179 countries/us-states/WA-53-washington-counties.... https://raw.githubusercontent.com/xoolive/topo... file 15542
180 countries/us-states/WI-55-wisconsin-counties.json https://raw.githubusercontent.com/xoolive/topo... file 25029
181 countries/us-states/WV-54-west-virginia-counti... https://raw.githubusercontent.com/xoolive/topo... file 19663
182 countries/us-states/WY-56-wyoming-counties.json https://raw.githubusercontent.com/xoolive/topo... file 8682
183 countries/venezuela/venezuela-estados.json https://raw.githubusercontent.com/xoolive/topo... file 84347

136 rows × 4 columns

Filtering the atlas collection

You can filter the table with regular accessors:

default.europe  # equivalent to from cartes.atlas import europe
path download_url type size
12 continents/europe.json https://raw.githubusercontent.com/xoolive/topo... file 26510

When only one element is left, you can access:

  • a topo_feature element, for a direct access in Altair.
    Here, data is not included in the Altair JSON, only a link to the url.
  • a data element for the corresponding Geopandas dataframe.
    This option is comfortable for exploring data, or for further postprocessing.
import altair as alt

from cartes.atlas import europe
from cartes.crs import EuroPP

(
    alt.Chart(europe.topo_feature)
    .mark_geoshape(stroke="white")
    .project(**EuroPP())
    .configure_view(stroke=None)
    .properties(width=400, height=400)
)

Corresponding data is available, and stored in cache:

europe.data.head()
id type geounit geometry
0 None Sovereigncountry Albania POLYGON ((20.06620 42.54630, 20.50071 42.20947...
1 None Sovereigncountry Andorra POLYGON EMPTY
2 None Sovereigncountry Austria POLYGON ((16.94629 48.60554, 16.84656 48.35953...
3 None Geounit FlemishRegion POLYGON ((5.65617 50.80821, 5.42823 50.72116, ...
4 None Sovereigncountry Bulgaria POLYGON ((28.57831 43.74225, 28.45721 43.37893...

It is possible to chain filtering:

from cartes.atlas import japan  # or from cartes.atlas.default import japan

japan
path download_url type size
82 countries/japan/jp-prefectures.json https://raw.githubusercontent.com/xoolive/topo... file 127013
83 countries/japan/jp-towns.json https://raw.githubusercontent.com/xoolive/topo... file 686798
japan.towns
path download_url type size
83 countries/japan/jp-towns.json https://raw.githubusercontent.com/xoolive/topo... file 686798

Simple maps

The data attribute is convenient to explore data and create a first visualisation:

japan.towns.data.query('NAME_1 == "Shiga"').iloc[:15, :10]
id ISO NAME_0 ID_1 NAME_1 ID_2 NAME_2 VARNAME_2 HASC_2 TYPE_2
1471 None JPN Japan 1492 Shiga 18424 Aisho Machi
1472 None JPN Japan 1492 Shiga 18425 Azuchi Machi
1473 None JPN Japan 1492 Shiga 18426 Higashiomi Shi
1474 None JPN Japan 1492 Shiga 18427 Hikone JP.SH.HK Shi
1475 None JPN Japan 1492 Shiga 18428 Hino Machi
1476 None JPN Japan 1492 Shiga 18429 Kinomoto Machi
1477 None JPN Japan 1492 Shiga 18430 Kohoku Machi
1478 None JPN Japan 1492 Shiga 18431 Koka Shi
1479 None JPN Japan 1492 Shiga 18432 Konan Shi
1480 None JPN Japan 1492 Shiga 18433 Kora Machi
1481 None JPN Japan 1492 Shiga 18434 Kusatsu JP.SH.KS Shi
1482 None JPN Japan 1492 Shiga 18435 Lake Biwa Water body
1483 None JPN Japan 1492 Shiga 18436 Maibara Shi
1484 None JPN Japan 1492 Shiga 18437 Moriyama JP.SH.MR Shi
1485 None JPN Japan 1492 Shiga 18438 Nagahama JP.SH.NG Shi
from cartes.crs import JGD2000

(
    alt.Chart(japan.towns.data.query('NAME_1 == "Shiga"'))
    .mark_geoshape(stroke="white")
    .encode(
        color=alt.condition(
            "datum.ENGTYPE_2 == 'Water body'",
            alt.value("steelblue"),
            alt.value("#bab0ac"),
        ),
        tooltip=alt.Tooltip("NAME_2"),
    )
    .project(**JGD2000())
    .configure_view(stroke=None)
    .properties(width=400, height=400)
)

Tip

If no postprocessing has been done on geometry, consider coming back to the topo_feature.

(
    alt.Chart(default.japan.towns.topo_feature)
    .mark_geoshape(stroke="white")
    .encode(
        color=alt.condition(
            "datum.properties.ENGTYPE_2 == 'Water body'",
            alt.value("steelblue"),
            alt.value("#bab0ac"),
        ),
        tooltip=alt.Tooltip("properties.NAME_2:N"),
    )
    .transform_filter("datum.properties.NAME_1 == 'Shiga'")
    .project(**JGD2000())
    .configure_view(stroke=None)
    .properties(width=400, height=400)
)

Warning

Note how the .query() becomes a .transform_filter() and how feature names are then prefixed with properties.

Tricks for filtering

  • A final _ in a filtering attribute negates it:

    from cartes.atlas import world
    
    world.countries
    
    path download_url type size
    7 world-countries-sans-antarctica.json https://raw.githubusercontent.com/xoolive/topo... file 109244
    8 world-countries.json https://raw.githubusercontent.com/xoolive/topo... file 115340
    world.countries.sans_
    
    path download_url type size
    8 world-countries.json https://raw.githubusercontent.com/xoolive/topo... file 115340
  • An attribute starting with a number yields a SyntaxError. Use the _ prefix:

    from cartes.atlas import world_atlas
    
    world_atlas.countries._10
    
    path hash size download_url
    0 countries-10m.json O8bx02epvOxHmEG64OdgkvUSg4QR0M7xJOku7E20X3k= 3661071 https://cdn.jsdelivr.net/npm/world-atlas@2.0.2...
    2 countries-110m.json JRbJFYZ8e68Y3exyeuxGwxVUGgfPs9eaZVmwXV6U7ug= 107761 https://cdn.jsdelivr.net/npm/world-atlas@2.0.2...

Tip

If you can’t find a work-around a special argument, try the .q() method and forget about SyntaxError:

world_atlas.q("countries").q("-10")
path hash size download_url
0 countries-10m.json O8bx02epvOxHmEG64OdgkvUSg4QR0M7xJOku7E20X3k= 3661071 https://cdn.jsdelivr.net/npm/world-atlas@2.0.2...