Polar opposites

Python
Altair
Antarctica
Author

José R. Ferrer-Paris

Published

August 19, 2024

So, I was looking at this map of the MT2.2 Large seabird and pinniped colonies ecosystem functional group, and was completely dissatisfied.

I mean, I am sure Gerardus Mercator was a great guy full of good intentions, but the polar distorsions are just ridiculous.

Lucky for us, there are so many projections and tools to visualise data from around the globe.

I will show you the problem and a nice solution using Python and just three ingredients: the packages altair, vega datasets and geopandas.

import altair as alt
from vega_datasets import data
import geopandas as gpd

The problem

First we load a simple map of the world:

countries = alt.topo_feature(data.world_110m.url, 'countries')

Now we will use the functions Chart, mark_geoshape and project to visualise this geospatial data using Mercator projection:

alt.Chart(countries).mark_geoshape(
    fill='lightgray',
    stroke='white'
).project(
    "mercator"
).properties(
    width=500,
    height=300
)

Yes, I know that all map projections create a distorted view of shapes or sizes of the true layout of the Earth’s surface. The main problem with Mercator projection is that exaggerates areas far from the equator; and that’s bad for circumpolar data.

The solution

Let’s just find a nice projection that helps us focus our poles of attention.

One nice way to visualise data on the ecosphere is to look at the Earth as if it were… well a sphere!

Let’s apply the orthographic map projection with specific rotation parameters and see how the results look like:

northpole = alt.Chart(countries).mark_geoshape(
    fill='gray',
    stroke='white'
).project(
    'orthographic',
    rotate=[75, -85, 15]
)

northpole

And looks much more round-y.

Add data on top of that

Now the interesting part is to add data to our globe view.

Let’s download this dataset in geojson format from:

Ferrer-Paris, J. R., Gorta, S. B. Z., & Keith, D. A. (2023). Indicative distribution map for Ecosystem Functional Group MT2.2 Large seabird and pinniped colonies (MT2.2.IM.orig v1.0) [Data set]. Zenodo. https://doi.org/10.5281/zenodo.10042530

Thanks Simon!

We use a function from geopandas to read this file:

url_geojson = 'https://zenodo.org/records/10042530/files/MT2.2.IM.orig_v1.0.json?download=1'
MT2_2 = gpd.read_file(url_geojson) 

MT2_2
occurrence name value geometry
0 major MT2.2 1 MULTIPOLYGON (((-170.31242 -77.70000, -158.816...
1 minor MT2.2 2 MULTIPOLYGON (((-5.51774 -72.81691, -5.24598 -...

Now we can apply the same projection parameters to this dataset:

ecomap_northpole = alt.Chart(MT2_2).mark_geoshape(
).encode(
    color='occurrence:N'
).project(
    'orthographic',
    rotate=[75, -85, 15]
)
ecomap_northpole

Upps! I forgot to combine both layers, silly me!

northpole + ecomap_northpole

What about the other end?

You mean the South Pole, right? Well, that is easy, we just need to rotate in the opposite direction.

Let’s do that for the country layer:

southpole = alt.Chart(countries).mark_geoshape(
    fill='gray',
    stroke='white'
).project(
    'orthographic',
    rotate=[75, 85, 15]
)

And the ecosystem layer

ecomap_southpole = alt.Chart(MT2_2).mark_geoshape(
).encode(
    color='occurrence:N'
).project(
    'orthographic',
    rotate=[75, 85, 15]
)

And this is it!

southpole + ecomap_southpole