How to Create Eye-Catching Country Rankings Using Python and Matplotlib

Hi, and welcome to this tutorial, where I’ll teach you to create a country ranking chart using Python and Matplotlib.

What I like about this visualization is its clean and beautiful way of showing how countries rank compared to each other on a particular metric.

The alternative to using a standard line chart showing the actual values get messy if some countries are close to each other or if some countries outperform others by a lot.

If you want access to the code for this tutorial, you can find it in this GitHub repository.

If you enjoy this tutorial, make sure to check out my other accounts.

Let’s get started.


About the data

I’ve created a simple CSV containing GDP values for today’s ten largest economies for this tutorial.

The data comes from the World Bank, and the full name of the indicator is “GDP (constant 2015 us$)”.

If you want to know more about different ways of measuring GDP, you can look at this Medium story, where I use the same type of data visualization.

Let’s get on with the tutorial.


Step 1: Creating rankings

Step one is to rank the countries for each year in the dataset, which is easy to do with pandas.

<span>def</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>columns</span><span>):</span>
<span>rank_columns</span> <span>=</span> <span>[</span><span>"</span><span>rank_{}</span><span>"</span><span>.</span><span>format</span><span>(</span><span>i</span><span>)</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>len</span><span>(</span><span>columns</span><span>))]</span>
<span>for</span> <span>i</span><span>,</span> <span>column</span> <span>in</span> <span>enumerate</span><span>(</span><span>columns</span><span>):</span>
<span>df</span><span>[</span><span>rank_columns</span><span>[</span><span>i</span><span>]]</span> <span>=</span> <span>df</span><span>[</span><span>column</span><span>].</span><span>rank</span><span>(</span><span>ascending</span><span>=</span><span>False</span><span>)</span>
<span>return</span> <span>df</span><span>,</span> <span>rank_columns</span>
<span>def</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>columns</span><span>):</span>
    <span>rank_columns</span> <span>=</span> <span>[</span><span>"</span><span>rank_{}</span><span>"</span><span>.</span><span>format</span><span>(</span><span>i</span><span>)</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>len</span><span>(</span><span>columns</span><span>))]</span>
    <span>for</span> <span>i</span><span>,</span> <span>column</span> <span>in</span> <span>enumerate</span><span>(</span><span>columns</span><span>):</span>
        <span>df</span><span>[</span><span>rank_columns</span><span>[</span><span>i</span><span>]]</span> <span>=</span> <span>df</span><span>[</span><span>column</span><span>].</span><span>rank</span><span>(</span><span>ascending</span><span>=</span><span>False</span><span>)</span>

    <span>return</span> <span>df</span><span>,</span> <span>rank_columns</span>
def create_rankings(df, columns): rank_columns = ["rank_{}".format(i) for i in range(len(columns))] for i, column in enumerate(columns): df[rank_columns[i]] = df[column].rank(ascending=False) return df, rank_columns

Enter fullscreen mode Exit fullscreen mode

The resulting columns look like this.

That’s all the preprocessing we need to continue with the data visualization.


Step 2: Creating and styling a grid

Now that we have prepared our data, it’s time to create a grid where we can draw our lines and flags.

Here’s a function using Seaborn that creates the overall style. It defines things like the background color and font family. I’m also removing spines and ticks.

<span>def</span> <span>set_style</span><span>(</span><span>font_family</span><span>,</span> <span>background_color</span><span>,</span> <span>grid_color</span><span>,</span> <span>text_color</span><span>):</span>
<span>sns</span><span>.</span><span>set_style</span><span>({</span>
<span>"</span><span>axes.facecolor</span><span>"</span><span>:</span> <span>background_color</span><span>,</span>
<span>"</span><span>figure.facecolor</span><span>"</span><span>:</span> <span>background_color</span><span>,</span>
<span>"</span><span>axes.grid</span><span>"</span><span>:</span> <span>True</span><span>,</span>
<span>"</span><span>axes.axisbelow</span><span>"</span><span>:</span> <span>True</span><span>,</span>
<span>"</span><span>grid.color</span><span>"</span><span>:</span> <span>grid_color</span><span>,</span>
<span>"</span><span>text.color</span><span>"</span><span>:</span> <span>text_color</span><span>,</span>
<span>"</span><span>font.family</span><span>"</span><span>:</span> <span>font_family</span><span>,</span>
<span>"</span><span>xtick.bottom</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>xtick.top</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>ytick.left</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>ytick.right</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>axes.spines.left</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>axes.spines.bottom</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>axes.spines.right</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>"</span><span>axes.spines.top</span><span>"</span><span>:</span> <span>False</span><span>,</span>
<span>}</span>
<span>)</span>
<span>def</span> <span>set_style</span><span>(</span><span>font_family</span><span>,</span> <span>background_color</span><span>,</span> <span>grid_color</span><span>,</span> <span>text_color</span><span>):</span>
    <span>sns</span><span>.</span><span>set_style</span><span>({</span>
        <span>"</span><span>axes.facecolor</span><span>"</span><span>:</span> <span>background_color</span><span>,</span>
        <span>"</span><span>figure.facecolor</span><span>"</span><span>:</span> <span>background_color</span><span>,</span>

        <span>"</span><span>axes.grid</span><span>"</span><span>:</span> <span>True</span><span>,</span>
        <span>"</span><span>axes.axisbelow</span><span>"</span><span>:</span> <span>True</span><span>,</span>

        <span>"</span><span>grid.color</span><span>"</span><span>:</span> <span>grid_color</span><span>,</span>

        <span>"</span><span>text.color</span><span>"</span><span>:</span> <span>text_color</span><span>,</span>
        <span>"</span><span>font.family</span><span>"</span><span>:</span> <span>font_family</span><span>,</span>

        <span>"</span><span>xtick.bottom</span><span>"</span><span>:</span> <span>False</span><span>,</span>
        <span>"</span><span>xtick.top</span><span>"</span><span>:</span> <span>False</span><span>,</span>
        <span>"</span><span>ytick.left</span><span>"</span><span>:</span> <span>False</span><span>,</span>
        <span>"</span><span>ytick.right</span><span>"</span><span>:</span> <span>False</span><span>,</span>

        <span>"</span><span>axes.spines.left</span><span>"</span><span>:</span> <span>False</span><span>,</span>
        <span>"</span><span>axes.spines.bottom</span><span>"</span><span>:</span> <span>False</span><span>,</span>
        <span>"</span><span>axes.spines.right</span><span>"</span><span>:</span> <span>False</span><span>,</span>
        <span>"</span><span>axes.spines.top</span><span>"</span><span>:</span> <span>False</span><span>,</span>
    <span>}</span>
<span>)</span>
def set_style(font_family, background_color, grid_color, text_color): sns.set_style({ "axes.facecolor": background_color, "figure.facecolor": background_color, "axes.grid": True, "axes.axisbelow": True, "grid.color": grid_color, "text.color": text_color, "font.family": font_family, "xtick.bottom": False, "xtick.top": False, "ytick.left": False, "ytick.right": False, "axes.spines.left": False, "axes.spines.bottom": False, "axes.spines.right": False, "axes.spines.top": False, } )

Enter fullscreen mode Exit fullscreen mode

I run the function with the following values.

<span>font_family</span> <span>=</span> <span>"</span><span>PT Mono</span><span>"</span>
<span>background_color</span> <span>=</span> <span>"</span><span>#FAF0F1</span><span>"</span>
<span>text_color</span> <span>=</span> <span>"</span><span>#080520</span><span>"</span>
<span>grid_color</span> <span>=</span> <span>"</span><span>#E4C9C9</span><span>"</span>
<span>set_style</span><span>(</span><span>font_family</span><span>,</span> <span>background_color</span><span>,</span> <span>grid_color</span><span>,</span> <span>text_color</span><span>)</span>
<span>font_family</span> <span>=</span> <span>"</span><span>PT Mono</span><span>"</span>
<span>background_color</span> <span>=</span> <span>"</span><span>#FAF0F1</span><span>"</span>
<span>text_color</span> <span>=</span> <span>"</span><span>#080520</span><span>"</span>
<span>grid_color</span> <span>=</span> <span>"</span><span>#E4C9C9</span><span>"</span>

<span>set_style</span><span>(</span><span>font_family</span><span>,</span> <span>background_color</span><span>,</span> <span>grid_color</span><span>,</span> <span>text_color</span><span>)</span>
font_family = "PT Mono" background_color = "#FAF0F1" text_color = "#080520" grid_color = "#E4C9C9" set_style(font_family, background_color, grid_color, text_color)

Enter fullscreen mode Exit fullscreen mode

To create the actual grid, I have a function that formats the y- and x-axis. It takes a few parameters that allow me to try different setups, such as the size of the labels.

<span>def</span> <span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>,</span> <span>padx</span><span>=</span><span>0.25</span><span>,</span> <span>pady</span><span>=</span><span>0.5</span><span>,</span> <span>y_label_size</span><span>=</span><span>20</span><span>,</span> <span>x_label_size</span><span>=</span><span>24</span><span>):</span>
<span>ax</span><span>.</span><span>set</span><span>(</span><span>xlim</span><span>=</span><span>(</span><span>-</span><span>padx</span><span>,</span> <span>len</span><span>(</span><span>years</span><span>)</span> <span>-</span><span>1</span> <span>+</span> <span>padx</span><span>),</span> <span>ylim</span><span>=</span><span>(</span><span>-</span><span>len</span><span>(</span><span>df</span><span>)</span> <span>-</span> <span>pady</span><span>,</span> <span>-</span> <span>pady</span><span>))</span>
<span>xticks</span> <span>=</span> <span>[</span><span>i</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>len</span><span>(</span><span>years</span><span>))]</span>
<span>ax</span><span>.</span><span>set_xticks</span><span>(</span><span>ticks</span><span>=</span><span>xticks</span><span>,</span> <span>labels</span><span>=</span><span>years</span><span>)</span>
<span>yticks</span> <span>=</span> <span>[</span><span>-</span><span>i</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>1</span><span>,</span> <span>len</span><span>(</span><span>df</span><span>)</span> <span>+</span> <span>1</span><span>)]</span>
<span>ylabels</span> <span>=</span> <span>[</span><span>"</span><span>{}</span><span>"</span><span>.</span><span>format</span><span>(</span><span>i</span><span>)</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>1</span><span>,</span> <span>len</span><span>(</span><span>df</span><span>)</span> <span>+</span> <span>1</span><span>)]</span>
<span>ax</span><span>.</span><span>set_yticks</span><span>(</span><span>ticks</span><span>=</span><span>yticks</span><span>,</span> <span>labels</span><span>=</span><span>ylabels</span><span>)</span>
<span>ax</span><span>.</span><span>tick_params</span><span>(</span><span>"</span><span>y</span><span>"</span><span>,</span><span>labelsize</span><span>=</span><span>y_label_size</span><span>,</span> <span>pad</span><span>=</span><span>16</span><span>)</span>
<span>ax</span><span>.</span><span>tick_params</span><span>(</span><span>"</span><span>x</span><span>"</span><span>,</span> <span>labeltop</span><span>=</span><span>True</span><span>,</span> <span>labelsize</span><span>=</span><span>x_label_size</span><span>,</span> <span>pad</span><span>=</span><span>8</span><span>)</span>
<span>def</span> <span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>,</span> <span>padx</span><span>=</span><span>0.25</span><span>,</span> <span>pady</span><span>=</span><span>0.5</span><span>,</span> <span>y_label_size</span><span>=</span><span>20</span><span>,</span> <span>x_label_size</span><span>=</span><span>24</span><span>):</span>
    <span>ax</span><span>.</span><span>set</span><span>(</span><span>xlim</span><span>=</span><span>(</span><span>-</span><span>padx</span><span>,</span> <span>len</span><span>(</span><span>years</span><span>)</span> <span>-</span><span>1</span> <span>+</span> <span>padx</span><span>),</span> <span>ylim</span><span>=</span><span>(</span><span>-</span><span>len</span><span>(</span><span>df</span><span>)</span> <span>-</span> <span>pady</span><span>,</span> <span>-</span> <span>pady</span><span>))</span>

    <span>xticks</span> <span>=</span> <span>[</span><span>i</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>len</span><span>(</span><span>years</span><span>))]</span>
    <span>ax</span><span>.</span><span>set_xticks</span><span>(</span><span>ticks</span><span>=</span><span>xticks</span><span>,</span> <span>labels</span><span>=</span><span>years</span><span>)</span>

    <span>yticks</span> <span>=</span> <span>[</span><span>-</span><span>i</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>1</span><span>,</span> <span>len</span><span>(</span><span>df</span><span>)</span> <span>+</span> <span>1</span><span>)]</span>
    <span>ylabels</span> <span>=</span> <span>[</span><span>"</span><span>{}</span><span>"</span><span>.</span><span>format</span><span>(</span><span>i</span><span>)</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>1</span><span>,</span> <span>len</span><span>(</span><span>df</span><span>)</span> <span>+</span> <span>1</span><span>)]</span>
    <span>ax</span><span>.</span><span>set_yticks</span><span>(</span><span>ticks</span><span>=</span><span>yticks</span><span>,</span> <span>labels</span><span>=</span><span>ylabels</span><span>)</span>

    <span>ax</span><span>.</span><span>tick_params</span><span>(</span><span>"</span><span>y</span><span>"</span><span>,</span><span>labelsize</span><span>=</span><span>y_label_size</span><span>,</span> <span>pad</span><span>=</span><span>16</span><span>)</span>
    <span>ax</span><span>.</span><span>tick_params</span><span>(</span><span>"</span><span>x</span><span>"</span><span>,</span> <span>labeltop</span><span>=</span><span>True</span><span>,</span> <span>labelsize</span><span>=</span><span>x_label_size</span><span>,</span> <span>pad</span><span>=</span><span>8</span><span>)</span>
def format_ticks(ax, years, padx=0.25, pady=0.5, y_label_size=20, x_label_size=24): ax.set(xlim=(-padx, len(years) -1 + padx), ylim=(-len(df) - pady, - pady)) xticks = [i for i in range(len(years))] ax.set_xticks(ticks=xticks, labels=years) yticks = [-i for i in range(1, len(df) + 1)] ylabels = ["{}".format(i) for i in range(1, len(df) + 1)] ax.set_yticks(ticks=yticks, labels=ylabels) ax.tick_params("y",labelsize=y_label_size, pad=16) ax.tick_params("x", labeltop=True, labelsize=x_label_size, pad=8)

Enter fullscreen mode Exit fullscreen mode

Here’s what it looks like when I run everything we have so far.

<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>
<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>
<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>

<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>
# Load data years = ["2000", "2005", "2010", "2015", "2020", "2022"] df = pd.read_csv("rankings.csv", index_col=None) df, rank_columns = create_rankings(df, years) # Create chart fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15, 1.6*len(df))) format_ticks(ax, years)

Enter fullscreen mode Exit fullscreen mode

And here’s the resulting grid.

Now we can start to add some data.


Step 3: Adding lines

I want a line showing each country’s rank for each year in the dataset—an easy task in Matplotlib.

<span>def</span> <span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>columns</span><span>,</span> <span>linewidth</span><span>=</span><span>3</span><span>):</span>
<span>x</span> <span>=</span> <span>[</span><span>i</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>len</span><span>(</span><span>columns</span><span>))]</span>
<span>y</span> <span>=</span> <span>[</span><span>-</span><span>row</span><span>[</span><span>rc</span><span>]</span> <span>for</span> <span>rc</span> <span>in</span> <span>columns</span><span>]</span>
<span>ax</span><span>.</span><span>add_artist</span><span>(</span>
<span>Line2D</span><span>(</span><span>x</span><span>,</span> <span>y</span><span>,</span> <span>linewidth</span><span>=</span><span>linewidth</span><span>,</span> <span>color</span><span>=</span><span>text_color</span><span>)</span>
<span>)</span>
<span>def</span> <span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>columns</span><span>,</span> <span>linewidth</span><span>=</span><span>3</span><span>):</span>
    <span>x</span> <span>=</span> <span>[</span><span>i</span> <span>for</span> <span>i</span> <span>in</span> <span>range</span><span>(</span><span>len</span><span>(</span><span>columns</span><span>))]</span>
    <span>y</span> <span>=</span> <span>[</span><span>-</span><span>row</span><span>[</span><span>rc</span><span>]</span> <span>for</span> <span>rc</span> <span>in</span> <span>columns</span><span>]</span>

    <span>ax</span><span>.</span><span>add_artist</span><span>(</span>
        <span>Line2D</span><span>(</span><span>x</span><span>,</span> <span>y</span><span>,</span> <span>linewidth</span><span>=</span><span>linewidth</span><span>,</span> <span>color</span><span>=</span><span>text_color</span><span>)</span>
    <span>)</span>
def add_line(ax, row, columns, linewidth=3): x = [i for i in range(len(columns))] y = [-row[rc] for rc in columns] ax.add_artist( Line2D(x, y, linewidth=linewidth, color=text_color) )

Enter fullscreen mode Exit fullscreen mode

Then I run the function for each row in the dataset like this.

<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>
<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>
<span># Draw lines </span><span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
<span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>
<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>

<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>

<span># Draw lines </span><span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
    <span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>
# Load data years = ["2000", "2005", "2010", "2015", "2020", "2022"] df = pd.read_csv("rankings.csv", index_col=None) df, rank_columns = create_rankings(df, years) # Create chart fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15, 1.6*len(df))) format_ticks(ax, years) # Draw lines for i, row in df.iterrows(): add_line(ax, row, rank_columns)

Enter fullscreen mode Exit fullscreen mode

I’m using the same color for each line because I want to use country flags to guide the eye. Using a unique color for each line makes sense, but it looks messy.


Step 4: Drawing pie charts

I want to indicate how a country’s economy grows over time without adding text. Instead, I aim to inform in a visual format.

My idea is to draw a pie chart on each point showing the size of a country’s economy compared to its best year.

I’m using PIL to create a pie chart image, but you can use Matplotlib directly. I don’t because I had some issues with aspect ratios.

<span>def</span> <span>add_pie</span><span>(</span><span>ax</span><span>,</span> <span>x</span><span>,</span> <span>y</span><span>,</span> <span>ratio</span><span>,</span> <span>size</span><span>=</span><span>572</span><span>,</span> <span>zoom</span><span>=</span><span>0.1</span><span>):</span>
<span>image</span> <span>=</span> <span>Image</span><span>.</span><span>new</span><span>(</span><span>'</span><span>RGBA</span><span>'</span><span>,</span> <span>(</span><span>size</span><span>,</span> <span>size</span><span>))</span>
<span>draw</span> <span>=</span> <span>ImageDraw</span><span>.</span><span>Draw</span><span>(</span><span>image</span><span>)</span>
<span>draw</span><span>.</span><span>pieslice</span><span>((</span><span>0</span><span>,</span> <span>0</span><span>,</span> <span>size</span><span>,</span> <span>size</span><span>),</span> <span>start</span><span>=-</span><span>90</span><span>,</span> <span>end</span><span>=</span><span>360</span><span>*</span><span>ratio</span><span>-</span><span>90</span><span>,</span> <span>fill</span><span>=</span><span>text_color</span><span>,</span> <span>outline</span><span>=</span><span>text_color</span><span>)</span>
<span>im</span> <span>=</span> <span>OffsetImage</span><span>(</span><span>image</span><span>,</span> <span>zoom</span><span>=</span><span>zoom</span><span>,</span> <span>interpolation</span><span>=</span><span>"</span><span>lanczos</span><span>"</span><span>,</span> <span>resample</span><span>=</span><span>True</span><span>,</span> <span>visible</span><span>=</span><span>True</span><span>)</span>
<span>ax</span><span>.</span><span>add_artist</span><span>(</span><span>AnnotationBbox</span><span>(</span>
<span>im</span><span>,</span> <span>(</span><span>x</span><span>,</span> <span>y</span><span>),</span> <span>frameon</span><span>=</span><span>False</span><span>,</span>
<span>xycoords</span><span>=</span><span>"</span><span>data</span><span>"</span><span>,</span>
<span>))</span>
<span>def</span> <span>add_pie</span><span>(</span><span>ax</span><span>,</span> <span>x</span><span>,</span> <span>y</span><span>,</span> <span>ratio</span><span>,</span> <span>size</span><span>=</span><span>572</span><span>,</span> <span>zoom</span><span>=</span><span>0.1</span><span>):</span>
    <span>image</span> <span>=</span> <span>Image</span><span>.</span><span>new</span><span>(</span><span>'</span><span>RGBA</span><span>'</span><span>,</span> <span>(</span><span>size</span><span>,</span> <span>size</span><span>))</span>
    <span>draw</span> <span>=</span> <span>ImageDraw</span><span>.</span><span>Draw</span><span>(</span><span>image</span><span>)</span>

    <span>draw</span><span>.</span><span>pieslice</span><span>((</span><span>0</span><span>,</span> <span>0</span><span>,</span> <span>size</span><span>,</span> <span>size</span><span>),</span> <span>start</span><span>=-</span><span>90</span><span>,</span> <span>end</span><span>=</span><span>360</span><span>*</span><span>ratio</span><span>-</span><span>90</span><span>,</span> <span>fill</span><span>=</span><span>text_color</span><span>,</span> <span>outline</span><span>=</span><span>text_color</span><span>)</span>
    <span>im</span> <span>=</span> <span>OffsetImage</span><span>(</span><span>image</span><span>,</span> <span>zoom</span><span>=</span><span>zoom</span><span>,</span> <span>interpolation</span><span>=</span><span>"</span><span>lanczos</span><span>"</span><span>,</span> <span>resample</span><span>=</span><span>True</span><span>,</span> <span>visible</span><span>=</span><span>True</span><span>)</span>

    <span>ax</span><span>.</span><span>add_artist</span><span>(</span><span>AnnotationBbox</span><span>(</span>
        <span>im</span><span>,</span> <span>(</span><span>x</span><span>,</span> <span>y</span><span>),</span> <span>frameon</span><span>=</span><span>False</span><span>,</span>
        <span>xycoords</span><span>=</span><span>"</span><span>data</span><span>"</span><span>,</span>
    <span>))</span>
def add_pie(ax, x, y, ratio, size=572, zoom=0.1): image = Image.new('RGBA', (size, size)) draw = ImageDraw.Draw(image) draw.pieslice((0, 0, size, size), start=-90, end=360*ratio-90, fill=text_color, outline=text_color) im = OffsetImage(image, zoom=zoom, interpolation="lanczos", resample=True, visible=True) ax.add_artist(AnnotationBbox( im, (x, y), frameon=False, xycoords="data", ))

Enter fullscreen mode Exit fullscreen mode

The value for the size parameter is slightly larger than the size of my flag images which are 512×512. Later, I want to paste the flags on the pie charts.

Here’s the updated code.

<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>
<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>
<span># Draw lines </span><span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
<span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>
<span>for</span> <span>j</span><span>,</span> <span>rc</span> <span>in</span> <span>enumerate</span><span>(</span><span>rank_columns</span><span>):</span>
<span>add_pie</span><span>(</span><span>ax</span><span>,</span> <span>j</span><span>,</span> <span>-</span><span>row</span><span>[</span><span>rc</span><span>],</span> <span>ratio</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>j</span><span>]]</span> <span>/</span> <span>row</span><span>[</span><span>years</span><span>].</span><span>max</span><span>())</span>
<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>

<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>

<span># Draw lines </span><span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
    <span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>

    <span>for</span> <span>j</span><span>,</span> <span>rc</span> <span>in</span> <span>enumerate</span><span>(</span><span>rank_columns</span><span>):</span>
        <span>add_pie</span><span>(</span><span>ax</span><span>,</span> <span>j</span><span>,</span> <span>-</span><span>row</span><span>[</span><span>rc</span><span>],</span> <span>ratio</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>j</span><span>]]</span> <span>/</span> <span>row</span><span>[</span><span>years</span><span>].</span><span>max</span><span>())</span>
# Load data years = ["2000", "2005", "2010", "2015", "2020", "2022"] df = pd.read_csv("rankings.csv", index_col=None) df, rank_columns = create_rankings(df, years) # Create chart fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15, 1.6*len(df))) format_ticks(ax, years) # Draw lines for i, row in df.iterrows(): add_line(ax, row, rank_columns) for j, rc in enumerate(rank_columns): add_pie(ax, j, -row[rc], ratio=row[years[j]] / row[years].max())

Enter fullscreen mode Exit fullscreen mode

And here’s the result.

It’s starting to look informative, so it’s time to make it beautiful.


Step 5: Adding flags

I love using flags in my charts because they are simply beautiful.

Here, the purpose of the flags is to make the chart visually appealing, explain which countries we’re looking at, and guide the eye along the lines.

I’m using these rounded flags. They require a license, so, unfortunately, I can’t share them, but you can find similar flags in other places.

I’ve had some issues getting the pie and flag to align perfectly, so instead of creating a separate function to add a flag, I’m rewriting the add_pie() function.

<span>def</span> <span>add_pie_and_flag</span><span>(</span><span>ax</span><span>,</span> <span>x</span><span>,</span> <span>y</span><span>,</span> <span>name</span><span>,</span> <span>ratio</span><span>,</span> <span>size</span><span>=</span><span>572</span><span>,</span> <span>zoom</span><span>=</span><span>0.1</span><span>):</span>
<span>flag</span> <span>=</span> <span>Image</span><span>.</span><span>open</span><span>(</span><span>"</span><span><location>/{}.png</span><span>"</span><span>.</span><span>format</span><span>(</span><span>name</span><span>.</span><span>lower</span><span>()))</span>
<span>image</span> <span>=</span> <span>Image</span><span>.</span><span>new</span><span>(</span><span>'</span><span>RGBA</span><span>'</span><span>,</span> <span>(</span><span>size</span><span>,</span> <span>size</span><span>))</span>
<span>draw</span> <span>=</span> <span>ImageDraw</span><span>.</span><span>Draw</span><span>(</span><span>image</span><span>)</span>
<span>pad</span> <span>=</span> <span>int</span><span>((</span><span>size</span> <span>-</span> <span>512</span><span>)</span> <span>/</span> <span>2</span><span>)</span>
<span>draw</span><span>.</span><span>pieslice</span><span>((</span><span>0</span><span>,</span> <span>0</span><span>,</span> <span>size</span><span>,</span> <span>size</span><span>),</span> <span>start</span><span>=-</span><span>90</span><span>,</span> <span>end</span><span>=</span><span>360</span><span>*</span><span>ratio</span><span>-</span><span>90</span><span>,</span> <span>fill</span><span>=</span><span>text_color</span><span>,</span> <span>outline</span><span>=</span><span>text_color</span><span>)</span>
<span>image</span><span>.</span><span>paste</span><span>(</span><span>flag</span><span>,</span> <span>(</span><span>pad</span><span>,</span> <span>pad</span><span>),</span> <span>flag</span><span>.</span><span>split</span><span>()[</span><span>-</span><span>1</span><span>])</span>
<span>im</span> <span>=</span> <span>OffsetImage</span><span>(</span><span>image</span><span>,</span> <span>zoom</span><span>=</span><span>zoom</span><span>,</span> <span>interpolation</span><span>=</span><span>"</span><span>lanczos</span><span>"</span><span>,</span> <span>resample</span><span>=</span><span>True</span><span>,</span> <span>visible</span><span>=</span><span>True</span><span>)</span>
<span>ax</span><span>.</span><span>add_artist</span><span>(</span><span>AnnotationBbox</span><span>(</span>
<span>im</span><span>,</span> <span>(</span><span>x</span><span>,</span> <span>y</span><span>),</span> <span>frameon</span><span>=</span><span>False</span><span>,</span>
<span>xycoords</span><span>=</span><span>"</span><span>data</span><span>"</span><span>,</span>
<span>))</span>
<span>def</span> <span>add_pie_and_flag</span><span>(</span><span>ax</span><span>,</span> <span>x</span><span>,</span> <span>y</span><span>,</span> <span>name</span><span>,</span> <span>ratio</span><span>,</span> <span>size</span><span>=</span><span>572</span><span>,</span> <span>zoom</span><span>=</span><span>0.1</span><span>):</span>
    <span>flag</span> <span>=</span> <span>Image</span><span>.</span><span>open</span><span>(</span><span>"</span><span><location>/{}.png</span><span>"</span><span>.</span><span>format</span><span>(</span><span>name</span><span>.</span><span>lower</span><span>()))</span>
    <span>image</span> <span>=</span> <span>Image</span><span>.</span><span>new</span><span>(</span><span>'</span><span>RGBA</span><span>'</span><span>,</span> <span>(</span><span>size</span><span>,</span> <span>size</span><span>))</span>
    <span>draw</span> <span>=</span> <span>ImageDraw</span><span>.</span><span>Draw</span><span>(</span><span>image</span><span>)</span>
    <span>pad</span> <span>=</span> <span>int</span><span>((</span><span>size</span> <span>-</span> <span>512</span><span>)</span> <span>/</span> <span>2</span><span>)</span>

    <span>draw</span><span>.</span><span>pieslice</span><span>((</span><span>0</span><span>,</span> <span>0</span><span>,</span> <span>size</span><span>,</span> <span>size</span><span>),</span> <span>start</span><span>=-</span><span>90</span><span>,</span> <span>end</span><span>=</span><span>360</span><span>*</span><span>ratio</span><span>-</span><span>90</span><span>,</span> <span>fill</span><span>=</span><span>text_color</span><span>,</span> <span>outline</span><span>=</span><span>text_color</span><span>)</span>
    <span>image</span><span>.</span><span>paste</span><span>(</span><span>flag</span><span>,</span> <span>(</span><span>pad</span><span>,</span> <span>pad</span><span>),</span> <span>flag</span><span>.</span><span>split</span><span>()[</span><span>-</span><span>1</span><span>])</span>

    <span>im</span> <span>=</span> <span>OffsetImage</span><span>(</span><span>image</span><span>,</span> <span>zoom</span><span>=</span><span>zoom</span><span>,</span> <span>interpolation</span><span>=</span><span>"</span><span>lanczos</span><span>"</span><span>,</span> <span>resample</span><span>=</span><span>True</span><span>,</span> <span>visible</span><span>=</span><span>True</span><span>)</span>

    <span>ax</span><span>.</span><span>add_artist</span><span>(</span><span>AnnotationBbox</span><span>(</span>
        <span>im</span><span>,</span> <span>(</span><span>x</span><span>,</span> <span>y</span><span>),</span> <span>frameon</span><span>=</span><span>False</span><span>,</span>
        <span>xycoords</span><span>=</span><span>"</span><span>data</span><span>"</span><span>,</span>
    <span>))</span>
def add_pie_and_flag(ax, x, y, name, ratio, size=572, zoom=0.1): flag = Image.open("<location>/{}.png".format(name.lower())) image = Image.new('RGBA', (size, size)) draw = ImageDraw.Draw(image) pad = int((size - 512) / 2) draw.pieslice((0, 0, size, size), start=-90, end=360*ratio-90, fill=text_color, outline=text_color) image.paste(flag, (pad, pad), flag.split()[-1]) im = OffsetImage(image, zoom=zoom, interpolation="lanczos", resample=True, visible=True) ax.add_artist(AnnotationBbox( im, (x, y), frameon=False, xycoords="data", ))

Enter fullscreen mode Exit fullscreen mode

I add it right after the pie chart function.

<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>
<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>
<span># Draw lines </span><span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
<span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>
<span>for</span> <span>j</span><span>,</span> <span>rc</span> <span>in</span> <span>enumerate</span><span>(</span><span>rank_columns</span><span>):</span>
<span>add_pie_and_flag</span><span>(</span>
<span>ax</span><span>,</span> <span>j</span><span>,</span> <span>-</span><span>row</span><span>[</span><span>rc</span><span>],</span>
<span>name</span><span>=</span><span>row</span><span>.</span><span>country_name</span><span>,</span>
<span>ratio</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>j</span><span>]]</span> <span>/</span> <span>row</span><span>[</span><span>years</span><span>].</span><span>max</span><span>()</span>
<span>)</span>
<span># Load data </span><span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>

<span># Create chart </span><span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>

<span># Draw lines </span><span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
    <span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>

    <span>for</span> <span>j</span><span>,</span> <span>rc</span> <span>in</span> <span>enumerate</span><span>(</span><span>rank_columns</span><span>):</span>
        <span>add_pie_and_flag</span><span>(</span>
            <span>ax</span><span>,</span> <span>j</span><span>,</span> <span>-</span><span>row</span><span>[</span><span>rc</span><span>],</span> 
            <span>name</span><span>=</span><span>row</span><span>.</span><span>country_name</span><span>,</span>
            <span>ratio</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>j</span><span>]]</span> <span>/</span> <span>row</span><span>[</span><span>years</span><span>].</span><span>max</span><span>()</span>
        <span>)</span>
# Load data years = ["2000", "2005", "2010", "2015", "2020", "2022"] df = pd.read_csv("rankings.csv", index_col=None) df, rank_columns = create_rankings(df, years) # Create chart fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15, 1.6*len(df))) format_ticks(ax, years) # Draw lines for i, row in df.iterrows(): add_line(ax, row, rank_columns) for j, rc in enumerate(rank_columns): add_pie_and_flag( ax, j, -row[rc], name=row.country_name, ratio=row[years[j]] / row[years].max() )

Enter fullscreen mode Exit fullscreen mode

And now you can behold the visual magic of using flags. It’s a huge difference compared to the previous output.

We suddenly have something that looks nice and is easy to understand. The last thing to do is to add some helpful information.


Step 5: Adding additional information

Since not everyone knows all the flags by heart, I want to add the country’s name to the right.

I also want to show the size of the economy and how each country compares to the highest ranking.

Here’s my code for doing that.

<span>def</span> <span>add_text</span><span>(</span><span>ax</span><span>,</span> <span>value</span><span>,</span> <span>max_value</span><span>,</span> <span>y</span><span>):</span>
<span>trillions</span> <span>=</span> <span>round</span><span>(</span><span>value</span> <span>/</span> <span>1e12</span><span>,</span> <span>1</span><span>)</span>
<span>ratio_to_max</span> <span>=</span> <span>round</span><span>(</span><span>100</span> <span>*</span> <span>value</span> <span>/</span> <span>max_value</span><span>,</span> <span>1</span><span>)</span>
<span>text</span> <span>=</span> <span>"</span><span>{}</span><span>\n</span><span>${:,}T ({}%)</span><span>"</span><span>.</span><span>format</span><span>(</span>
<span>row</span><span>.</span><span>country_name</span><span>,</span>
<span>trillions</span><span>,</span>
<span>ratio_to_max</span>
<span>)</span>
<span>ax</span><span>.</span><span>annotate</span><span>(</span>
<span>text</span><span>,</span> <span>(</span><span>1.03</span><span>,</span> <span>y</span><span>),</span>
<span>fontsize</span><span>=</span><span>20</span><span>,</span>
<span>linespacing</span><span>=</span><span>1.7</span><span>,</span>
<span>va</span><span>=</span><span>"</span><span>center</span><span>"</span><span>,</span>
<span>xycoords</span><span>=</span><span>(</span><span>"</span><span>axes fraction</span><span>"</span><span>,</span> <span>"</span><span>data</span><span>"</span><span>)</span>
<span>)</span>
<span>def</span> <span>add_text</span><span>(</span><span>ax</span><span>,</span> <span>value</span><span>,</span> <span>max_value</span><span>,</span> <span>y</span><span>):</span>
    <span>trillions</span> <span>=</span> <span>round</span><span>(</span><span>value</span> <span>/</span> <span>1e12</span><span>,</span> <span>1</span><span>)</span>
    <span>ratio_to_max</span> <span>=</span> <span>round</span><span>(</span><span>100</span> <span>*</span> <span>value</span> <span>/</span> <span>max_value</span><span>,</span> <span>1</span><span>)</span>

    <span>text</span> <span>=</span> <span>"</span><span>{}</span><span>\n</span><span>${:,}T ({}%)</span><span>"</span><span>.</span><span>format</span><span>(</span>
        <span>row</span><span>.</span><span>country_name</span><span>,</span> 
        <span>trillions</span><span>,</span>
        <span>ratio_to_max</span>
    <span>)</span>

    <span>ax</span><span>.</span><span>annotate</span><span>(</span>
        <span>text</span><span>,</span> <span>(</span><span>1.03</span><span>,</span> <span>y</span><span>),</span> 
        <span>fontsize</span><span>=</span><span>20</span><span>,</span>
        <span>linespacing</span><span>=</span><span>1.7</span><span>,</span>
        <span>va</span><span>=</span><span>"</span><span>center</span><span>"</span><span>,</span>
        <span>xycoords</span><span>=</span><span>(</span><span>"</span><span>axes fraction</span><span>"</span><span>,</span> <span>"</span><span>data</span><span>"</span><span>)</span>
    <span>)</span>
def add_text(ax, value, max_value, y): trillions = round(value / 1e12, 1) ratio_to_max = round(100 * value / max_value, 1) text = "{}\n${:,}T ({}%)".format( row.country_name, trillions, ratio_to_max ) ax.annotate( text, (1.03, y), fontsize=20, linespacing=1.7, va="center", xycoords=("axes fraction", "data") )

Enter fullscreen mode Exit fullscreen mode

As before, I add the function to the main code block. Note that I’m also adding a title.

<span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>
<span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>
<span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
<span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>
<span>for</span> <span>j</span><span>,</span> <span>rc</span> <span>in</span> <span>enumerate</span><span>(</span><span>rank_columns</span><span>):</span>
<span>add_pie_and_flag</span><span>(</span>
<span>ax</span><span>,</span> <span>j</span><span>,</span> <span>-</span><span>row</span><span>[</span><span>rc</span><span>],</span>
<span>name</span><span>=</span><span>row</span><span>.</span><span>country_name</span><span>,</span>
<span>ratio</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>j</span><span>]]</span> <span>/</span> <span>row</span><span>[</span><span>years</span><span>].</span><span>max</span><span>()</span>
<span>)</span>
<span>add_text</span><span>(</span><span>ax</span><span>,</span> <span>value</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>-</span><span>1</span><span>]],</span> <span>max_value</span><span>=</span><span>df</span><span>.</span><span>iloc</span><span>[</span><span>0</span><span>][</span><span>years</span><span>[</span><span>-</span><span>1</span><span>]],</span> <span>y</span><span>=-</span><span>(</span><span>i</span> <span>+</span> <span>1</span><span>))</span>
<span>plt</span><span>.</span><span>title</span><span>(</span><span>"</span><span>Comparing Today</span><span>'</span><span>s Largest Economies</span><span>\n</span><span>GDP (constant 2015 us$)</span><span>"</span><span>,</span> <span>linespacing</span><span>=</span><span>1.8</span><span>,</span> <span>fontsize</span><span>=</span><span>32</span><span>,</span> <span>x</span><span>=</span><span>0.58</span><span>,</span> <span>y</span><span>=</span><span>1.12</span><span>)</span>
<span>years</span> <span>=</span> <span>[</span><span>"</span><span>2000</span><span>"</span><span>,</span> <span>"</span><span>2005</span><span>"</span><span>,</span> <span>"</span><span>2010</span><span>"</span><span>,</span> <span>"</span><span>2015</span><span>"</span><span>,</span> <span>"</span><span>2020</span><span>"</span><span>,</span> <span>"</span><span>2022</span><span>"</span><span>]</span>
<span>df</span> <span>=</span> <span>pd</span><span>.</span><span>read_csv</span><span>(</span><span>"</span><span>rankings.csv</span><span>"</span><span>,</span> <span>index_col</span><span>=</span><span>None</span><span>)</span>
<span>df</span><span>,</span> <span>rank_columns</span> <span>=</span> <span>create_rankings</span><span>(</span><span>df</span><span>,</span> <span>years</span><span>)</span>

<span>fig</span><span>,</span> <span>ax</span> <span>=</span> <span>plt</span><span>.</span><span>subplots</span><span>(</span><span>nrows</span><span>=</span><span>1</span><span>,</span> <span>ncols</span><span>=</span><span>1</span><span>,</span> <span>figsize</span><span>=</span><span>(</span><span>15</span><span>,</span> <span>1.6</span><span>*</span><span>len</span><span>(</span><span>df</span><span>)))</span>
<span>format_ticks</span><span>(</span><span>ax</span><span>,</span> <span>years</span><span>)</span>

<span>for</span> <span>i</span><span>,</span> <span>row</span> <span>in</span> <span>df</span><span>.</span><span>iterrows</span><span>():</span>
    <span>add_line</span><span>(</span><span>ax</span><span>,</span> <span>row</span><span>,</span> <span>rank_columns</span><span>)</span>

    <span>for</span> <span>j</span><span>,</span> <span>rc</span> <span>in</span> <span>enumerate</span><span>(</span><span>rank_columns</span><span>):</span>
        <span>add_pie_and_flag</span><span>(</span>
            <span>ax</span><span>,</span> <span>j</span><span>,</span> <span>-</span><span>row</span><span>[</span><span>rc</span><span>],</span> 
            <span>name</span><span>=</span><span>row</span><span>.</span><span>country_name</span><span>,</span>
            <span>ratio</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>j</span><span>]]</span> <span>/</span> <span>row</span><span>[</span><span>years</span><span>].</span><span>max</span><span>()</span>
        <span>)</span>

    <span>add_text</span><span>(</span><span>ax</span><span>,</span> <span>value</span><span>=</span><span>row</span><span>[</span><span>years</span><span>[</span><span>-</span><span>1</span><span>]],</span> <span>max_value</span><span>=</span><span>df</span><span>.</span><span>iloc</span><span>[</span><span>0</span><span>][</span><span>years</span><span>[</span><span>-</span><span>1</span><span>]],</span> <span>y</span><span>=-</span><span>(</span><span>i</span> <span>+</span> <span>1</span><span>))</span>
    <span>plt</span><span>.</span><span>title</span><span>(</span><span>"</span><span>Comparing Today</span><span>'</span><span>s Largest Economies</span><span>\n</span><span>GDP (constant 2015 us$)</span><span>"</span><span>,</span> <span>linespacing</span><span>=</span><span>1.8</span><span>,</span> <span>fontsize</span><span>=</span><span>32</span><span>,</span> <span>x</span><span>=</span><span>0.58</span><span>,</span> <span>y</span><span>=</span><span>1.12</span><span>)</span>
years = ["2000", "2005", "2010", "2015", "2020", "2022"] df = pd.read_csv("rankings.csv", index_col=None) df, rank_columns = create_rankings(df, years) fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15, 1.6*len(df))) format_ticks(ax, years) for i, row in df.iterrows(): add_line(ax, row, rank_columns) for j, rc in enumerate(rank_columns): add_pie_and_flag( ax, j, -row[rc], name=row.country_name, ratio=row[years[j]] / row[years].max() ) add_text(ax, value=row[years[-1]], max_value=df.iloc[0][years[-1]], y=-(i + 1)) plt.title("Comparing Today's Largest Economies\nGDP (constant 2015 us$)", linespacing=1.8, fontsize=32, x=0.58, y=1.12)

Enter fullscreen mode Exit fullscreen mode

Voila.

That’s it; we’re done.


Conclusion

Today, you’ve learned an alternative way to visualize.

I like this type of data visualization because it’s easy on the eye and conveys a ton of information with very little text.

If you enjoyed it as much as I did, make sure to subscribe to my channel for more of the same! 🙂

Thank you for reading.

原文链接:How to Create Eye-Catching Country Rankings Using Python and Matplotlib

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
Change your thoughts and you change your world.
改变你的思想,你就能改变自己的命运
评论 抢沙发

请登录后发表评论

    暂无评论内容