countries = geo_countries.merge(countries_df, on='name')
scaledown = False
# epsg = 25832 # UTM Zone 32N, good for germany, does not work on global scale
# epsg = 4087
# epsg = 3395
# epsg = 4326
# ...
# EPSG:3857 is the original projection CRS of the background map and thus the map corresponds to the computed projection error. So in this case we can scale geometries down to show true sizes of countries.
epsg, scaledown = 3857, True
countries = countries.to_crs(f'EPSG:{epsg}')
# calculate relative difference of projected and reference areas
countries['proj_area'] = countries.area / 1e6 # in km²
ratio = countries['proj_area'] / countries['ref_area']
countries['rel_diff_area'] = ((ratio - 1).round(2) * 100).astype(int) # in percent
if scaledown:
# split MultiPolygons into separate Polygons, e. g. 1 MultiPolygon of Germany → 6 Polygons (6 rows with the same data)
countries = countries.explode()
countries = countries.explode(index_parts=False)
# scale down each poly
scale = 1 / np.sqrt(ratio)
countries.geometry = [affinity.scale(g, s, s) for g, s in zip(countries.geometry, scale[countries.index])]
# special handling for Antarctica, since it would be below the visible area