Print

Dumbbell charts in matplotlib

In this tutorial I will show you how to create Dumbbell charts using Python and Matplotlib. For more matplotlib charts, check out the gallery:

1 dataset 100 matplotlib visualizations
Python dataviz gallery, matplotlib viz gallery

Important notes:

1. This are my personal notes, so apologies if some explanations and notations are missing.

Dumbbell charts in matplotlib

Click on the links to go to the specific tutorials:

  1. Dumbell (19_1)
  2. Dumbell (19)
  3. Dumbell (20)

Import the packages

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.lines import Line2D

Add necessary columns:

color_dict = {"Norway": "#2B314D", "Denmark": "#A54836", "Sweden": "#5375D4", }

xy_ticklabel_color,  grid_color, datalabels_color ='#757C85', "#C8C9C9", "#FFFFFF"

data = {
    "year": [2004, 2022, 2004, 2022, 2004, 2022],
    "countries" : [ "Denmark", "Denmark", "Norway", "Norway","Sweden", "Sweden",],
    "sites": [4,10,5,8,13,15]
}
df= pd.DataFrame(data)
df = df.sort_values(['year','sites'  ], ascending=False ).reset_index(drop=True)
#map the colors of a dict to a dataframe
df['color']= df.countries.map(color_dict)
df
yearcountriessitescolor
02022Sweden15#5375D4
12022Denmark10#A54836
22022Norway8#2B314D
32004Sweden13#5375D4
42004Norway5#2B314D
52004Denmark4#A54836

Define the variables

unique_countries = df.countries.unique()
countries = df.countries
colors = df.color.unique()

Create the plot

fig, ax = plt.subplots(figsize=(8,3), facecolor = "#FFFFFF")


for color, country in zip(colors,unique_countries):
    temp_df= df[df.countries ==country]
    ax.plot(temp_df.sites, temp_df.countries, '-o', markersize = 12, mec = "w", mew=2, color = color, zorder=1)

# Set xlim
ax.set_xlim(0, df.sites.max()+3)

ax.xaxis.set_tick_params(labeltop=True,      # Put x-axis labels on top
                         labelbottom=False,  # Set no x-axis labels on bottom
                         bottom=False,       # Set no ticks on bottom
                         labelsize=11,       # Set tick label size
                         pad=10)             # Lower tick labels a bit

# Create grid 
ax.grid(which="major", axis='both', color='#758D99', alpha=0.6, zorder=1)


# Remove splines. Can be done one at a time or can slice with a list.
ax.spines[['top','right','bottom']].set_visible(False)

#add legend
lines = [Line2D([0], [0], color=c,  marker='o',linestyle='', markersize=8,) for c in reversed(colors)]

plt.legend(lines, reversed(countries), labelcolor = xy_ticklabel_color,
           prop=dict(weight='light', size=10), 
           bbox_to_anchor=(0.5, -0.25), loc="lower center",
            ncols = 3,frameon=False, fontsize= 14)
19 of 100: Dumbell chart in matplotlib
Was this helpful?

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents