About
This plot is a choropleth map. It show the CO2 emissions per capita in 2021 for each country.
The chart was made by Joseph Barbier. Thanks to him for accepting sharing his work here!
Let's see what the final picture will look like:
Libraries
First, you need to install the following librairies:
- matplotlib is used for creating the chart and add customization features
- pandas and
geopandas
are used to put the data into a dataframe and manipulate geographical data - drawarrow for the arrows
- pyfonts for the fonts
geopandas
: for the geographical datahighlight_text
: to add beautiful annotations to the chart
And that's it!
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
from pypalettes import load_cmap
from matplotlib.font_manager import FontProperties
from drawarrow import fig_arrow
from pyfonts import load_font
from highlight_text import fig_text, ax_text
Dataset
Creating a choropleth map necessitates a dataset with geographical information. For this example, we need to load the world map from the Gallery's repo.
Next, we should load the dataset containing the values we want to represent on the map, such as CO2 per capita by country. This dataset is also accessible in the Gallery's repo.
url = "https://raw.githubusercontent.com/holtzy/the-python-graph-gallery/master/static/data/europe.geojson"
world = gpd.read_file(url)
world.head()
pop_est | continent | name | iso_a3 | gdp_md_est | geometry | |
---|---|---|---|---|---|---|
0 | 144373535.0 | Europe | Russia | RUS | 1699876 | MULTIPOLYGON (((180.00000 71.51571, 180.00000 ... |
1 | 5347896.0 | Europe | Norway | NOR | 403336 | MULTIPOLYGON (((15.14282 79.67431, 15.52255 80... |
2 | 67059887.0 | Europe | France | FRA | 2715518 | MULTIPOLYGON (((-51.65780 4.15623, -52.24934 3... |
3 | 10285453.0 | Europe | Sweden | SWE | 530883 | POLYGON ((11.02737 58.85615, 11.46827 59.43239... |
4 | 9466856.0 | Europe | Belarus | BLR | 63080 | POLYGON ((28.17671 56.16913, 29.22951 55.91834... |
Now we merge this dataset with the world map with a merge
function. This function will match the country names in the two datasets and add the CO2 values to the world map dataframe.
url = "https://raw.githubusercontent.com/holtzy/the-python-graph-gallery/master/static/data/co2PerCapita.csv"
df = pd.read_csv(url)
# merge data
data = world.merge(df, how='left', left_on='name', right_on='Country')
# filter to keep only specific countries
data = data[data['continent'] == 'Europe']
data = data[~data['name'].isin(['Russia', 'Iceland'])]
data = data[data['Year'] == 2021]
data = data[['name', 'Total', 'geometry']]
data = data.dropna()
data.head()
name | Total | geometry | |
---|---|---|---|
543 | Norway | 7.573273 | MULTIPOLYGON (((15.14282 79.67431, 15.52255 80... |
815 | France | 4.741312 | MULTIPOLYGON (((-51.65780 4.15623, -52.24934 3... |
1087 | Sweden | 3.424918 | POLYGON ((11.02737 58.85615, 11.46827 59.43239... |
1359 | Belarus | 6.222741 | POLYGON ((28.17671 56.16913, 29.22951 55.91834... |
1631 | Ukraine | 4.637058 | POLYGON ((32.15944 52.06125, 32.41206 52.28869... |
Background map
Thanks to the geopandas
library, we can easily add a background map to our plot by simply calling the plot()
function on our geo dataframe.
With just a few lines of code, we can create a synthetic map that displays a European map.
# initialize the figure
fig, ax = plt.subplots(figsize=(10, 10), dpi=300)
# create the plot
data.plot(ax=ax)
plt.show()
Custom axis
The next step is to adjust the plot's ranges (latitude and longitude) using the set_xlim()
and set_ylim()
functions on the axis object.
We also remove the spines around the map since they are not particularly useful in this context.
# initialize the figure
fig, ax = plt.subplots(figsize=(10, 10), dpi=300)
# create the plot
data.plot(ax=ax)
# custom axis
ax.set_xlim(-11, 41)
ax.set_ylim(32, 73)
ax.set_axis_off()
plt.show()
Choropleth map
A choropleth map is distinct from a background map because it employs color gradients to depict data, with each country shaded according to its data value.
We initiate by loading a colormap via the load_cmap()
function from the pypalettes library, subsequently integrating this colormap into the plot by including cmap=cmap
in the plot()
function.
To enhance readability, we also define the edgecolor
and linewidth
of the countries.
# load colormap
cmap = load_cmap('BrwnYl', cmap_type='continuous')
# initialize the figure
fig, ax = plt.subplots(figsize=(10, 10), dpi=300)
# create the plot
data.plot(ax=ax, column='Total', cmap=cmap, edgecolor='black', linewidth=0.5)
# custom axis
ax.set_xlim(-11, 41)
ax.set_ylim(32, 73)
ax.set_axis_off()
plt.show()