Column Non-Null Count Dtype
Data visualization is a powerful tool for exploring and communicating insights from data. While static charts and graphs are helpful, dynamic and animated visualizations can be even more impactful by showing how data changes over time. One compelling example of this is the bar chart race.
A bar chart race is an animated bar chart that shows changing values over time, with bars representing different categories rising and falling based on their relative values at each point in time. This results in an engaging animation that reveals patterns, rankings, and movement in the underlying data.
In this post, we‘ll walk through how to create a bar chart race to visualize world population data from 1950 to 2020 using Python. We‘ll leverage the bar_chart_race package to generate the animation and customize various visual elements. Let‘s get started!
The Dataset
The dataset we‘ll be using contains population data for countries around the world from 1950 to 2020 in 5 year increments. It has 14,491 rows and 5 columns:
- Country – name of the country
- Year – year of the population estimate
- Population – total midyear population
- Yearly Change – absolute change in population from the previous year
- Percent Change – percent change in population from the previous year
Here‘s a preview of the first few rows:

As we can see, the data is in a tidy format with each row representing a unique country-year combination. This will make it easy to process and reshape the data as needed for the bar chart race.
Preprocessing the Data
To create our visualization, we first need to get the data in the right format. The bar_chart_race package expects the data in a wide format with:
- Each row representing a time period
- Each column representing a category (in our case countries)
- Values being the metric of interest at each time period for each category
To reshape our data, we‘ll use pandas‘ pivot_table function. But first, let‘s load the CSV into a DataFrame and take a look:
import pandas as pddf = pd.read_csv("population_by_country_1950_2020.csv") print(df.head()) print(df.info())
This outputs:
Country Year Population Yearly Change Percent Change
0 Afghanistan 1950 7752118 -- --
1 Afghanistan 1955 8817447 1065329 13.75
2 Afghanistan 1960 9829450 1012003 11.48
3 Afghanistan 1965 11173642 1344192 13.68
4 Afghanistan 1970 13356511 2182869 19.53
<class ‘pandas.core.frame.DataFrame‘>
RangeIndex: 14491 entries, 0 to 14490
Data columns (total 5 columns):
0 Country 14491 non-null object
1 Year 14491 non-null int64
2 Population 14491 non-null int64
3 Yearly Change 14279 non-null object
4 Percent Change 14279 non-null object
dtypes: int64(2), object(3)
memory usage: 566.3+ KB
We can see the DataFrame has the expected 14,491 rows and 5 columns, with the Population column containing integer values.
To reshape this, we‘ll use pivot_table, specifying Population as the value, Year as the index, and Country as the columns:
df_pivoted = df.pivot_table(
values="Population",
index="Year",
columns="Country"
).fillna(0)
print(df_pivoted.head())
Which results in:
Country Afghanistan Albania Algeria Andorra Angola ... Year ... 1950 7752118.0 1263291.0 8872718.0 5732.0 4117880.0 ... 1955 8817447.0 1466040.0 9714333.0 6377.0 4561036.0 ... 1960 9829450.0 1659800.0 10799997.0 8546.0 5201565.0 ... 1965 11173642.0 1896200.0 11923513.0 13411.0 5735901.0 ... 1970 13356511.0 2150800.0 13746184.0 19860.0 6141036.0 ...
We now have the data in the desired format, with years as the index, country names as columns, and population values as the integers. The DataFrame has 15 rows (one per 5 year increment from 1950 to 2020) and 217 columns (one per country).
Creating the Bar Chart Race
With our data ready, we can now generate the bar chart race using the bar_chart_race package. First, let‘s import it:
import bar_chart_race as bcr
The main function from the package, bar_chart_race, accepts the wide-format DataFrame as its first argument. It contains many additional parameters to customize the resulting visualization – here are a few key ones:
- n_bars: The maximum number of bars to show in each frame
- sort: How to sort the bars in each frame (‘desc‘ for descending)
- fixed_max: Whether to fix the maximum value of the axis across frames
- steps_per_period: Number of steps to go from one time period to the next
- period_length: Number of milliseconds to animate each period
- figsize: Dimensions of the output figure
- title: Title of the animation
- bar_label_size: Size of labels on the bars
- tick_label_size: Size of labels on the axis ticks
Let‘s put this together to create our bar chart race:
bcr.bar_chart_race(
df_pivoted,
n_bars=10,
sort=‘desc‘,
fixed_max=True,
steps_per_period=20,
period_length=1000,
figsize=(8, 6),
title=‘Top 10 Countries by Population 1950-2020‘,
bar_label_size=8,
tick_label_size=8
)
This code generates the following animated bar chart race:

Let‘s break down what we‘re seeing:
- The chart shows the top 10 countries by population at each year from 1950 to 2020
- China and India maintain the top 2 spots across the entire time period, with their populations rising significantly
- The US remains in 3rd place, while countries like Indonesia, Pakistan, Brazil, Nigeria, and Bangladesh enter the top 10 over time
- By the end, 7 of the top 10 countries are in Asia, with Nigeria as the most populous African nation and Brazil as the top South American country
- Overall population numbers increase dramatically over the 70 year span, with the top 10 countries totaling around 4.5 billion people by 2020 compared to about 1.5 billion in 1950
This animation provides an engaging and intuitive way to understand high-level trends in global population growth over time. While the underlying data contains over 200 countries across 15 time periods, the bar chart race allows us to focus on the biggest countries and how their relative rankings change.
Customizing the Visualization
The code above leverages several arguments to customize the look and feel of the bar chart race:
- Setting n_bars to 10 limits each frame to showing only the top 10 countries by population
- Specifying sort as ‘desc‘ orders the bars from highest to lowest values
- fixed_max=True fixes the maximum value of the axis across all frames, as opposed to having it change dynamically based on the values in each frame
- steps_per_period and period_length control the smoothness and speed of the animation
- figsize sets the dimensions of the output figure
- title adds a custom title to the top of the animation
- bar_label_size and tick_label_size adjust the font sizes of labels on the bars and axis ticks
There are many additional parameters to the bar_chart_race function that can be used to further customize the visualization. Some examples include:
- Coloring the bars using a custom color map
- Displaying the total population value at the top of each frame
- Formatting the bar labels and axis ticks
- Outputting the animation to a video file
- Providing custom easing functions to control the rates at which bars grow/shrink
The documentation provides a full list of available arguments.
Conclusion
In this post, we walked through the process of creating an animated bar chart race to visualize global population data over time. We started with a dataset in a tidy format, reshaped it using pandas‘ pivot_table function, and then generated the bar chart race using the bar_chart_race package.
The resulting animation provides an engaging way to understand high-level trends in population growth, showing how the rankings of countries changed over the past 70 years and putting the overall scale of global population increase into perspective.
While we focused on a specific dataset in this example, the same approach can be used to visualize any time series data with categories that can be ranked. Examples include stock prices, sales figures, sports standings, and much more. The bar_chart_race package makes it straightforward to turn data into a compelling animated visualization.
I encourage you to try it out on your own data and share what insights you discover!
Additional Resources
- bar_chart_race package documentation: https://github.com/dexplo/bar_chart_race
- Source code for this example: [Link to GitHub repo]
- An introduction to data visualization with Matplotlib: https://heartbeat.fritz.ai/data-visualization-with-python-matplotlib-ceffad1a367d
- Animated Data Visualizations in Python, with bar_chart_race & Plotly: https://medium.com/plotly/exploring-animations-in-python-with-bar-chart-race-mapsmapsmaps-and-plotly-64117b93c087