One day I wondered how would world look like if the countries were scaled according to their economic output. I found some maps based on the idea but none of them really looked good enough or recent enough. So I decided to make my own.

Getting the data

I found out there is a great BigQuery public dataset provided by World Bank that contains large number of World Development Indicators (WDI) including PPP, GDP and land area of the country. Data could be retrieved using relatively simple query:

SELECT

country_code,

country_name,

MAX(CASE WHEN indicator_name = 'Land area (sq. km)' THEN value END) AS land_area,

MAX(CASE WHEN indicator_name = 'GDP (current US$)' THEN value END) AS gdp,

MAX(CASE WHEN indicator_name = 'GDP, PPP (current international $)' THEN value END) AS ppp

FROM

(

SELECT

country_code,

country_name,

indicator_name,

year,

ROW_NUMBER() OVER (PARTITION BY country_code,indicator_name ORDER BY year DESC) AS rank,

value

FROM

`bigquery-public-data.world_bank_wdi.indicators_data` as indicators

) as a

WHERE rank = 1

GROUP BY 1,2

order by 5 desc

PARTITION BY makes sure that I’d get the PPP value for the most recent year available for the country. In the end I will use only PPP values and country_codes.

Getting map containing polygons of countries

Luckily there is a great repository containing all borders in GeoJson format. This will provide all the data we need for finishing the scaled map.

Scaling countries

The trickiest part is to scale countries in a way that looks good, keeps country shape intact and limits intersecting countries. I wrote a short and messy python script for the task. This is a simplified version:

# LOADS GEOJSON of country one by one as shapely object

# GET SIZE OF GEOMETRY AREA

land_area = (calculate_km2(geometry))

# CALCULATE PPP per sqkm

ppp_sqkm = country_gdp / land_area

# Calculate how much to scale the country area

# 1e7 is approx ppp_sqkm of European states so they do not intersect # when scaling

country_scale = 1/ (10000000 / ppp_sqkm)

# Square the scale to get the correct area

country_scale = sqrt(country_scale)

# Scale the area on centroid

scaled = shapely.affinity.scale(geometry, xfact=country_scale, yfact=country_scale, zfact=country_scale, origin='centroid')

# Simplify geometry

scaled = scaled.simplify(0.01)

Multi polygon countries were needed to be scaled per polygon and polygons that were too small were filtered out.

Formula country_scale = 1000000 / ppp_sqkm is based on the fact that PPP dense European countries and Japan are scaled almost 1:1 at this ratio. With smaller number European countries and Japan borders would be bleeding over neighboring countries.

Picking map projection

People are aware that map projections might distort reality. Map projections generaly used online have a lot of pros but area preserving is not a one of them. Usual suspect is the enlarged areas around the poles. That is why I had to pick so called Equal-area (Area preserving) map. This is a Mollweide projection and it should serve well for my use case.

Using QGIS I imported original countries and scaled countries.

Countries scaled according to their PPP. WGS 84

QGIS proved to be very unstable on Ubuntu with all countries loaded as layers but I was able to switch projection to Mollweide and export output as SVG.

Countries scaled according to their PPP. Mollweide projection.

Final touch

Using InkScape I was able to load layers from QGIS and add some text and coloring. Final product: