In this matplotlib tutorial, I will be showing you how to create a waffle chart. A waffle chart is a great tool to visualize a progress, comparisons, and also a key skill to add to your portfolio if you want to become better at data visualization with Python.
A waffle chart shows progress towards a target or a completion percentage. There is a grid of small cells, of which colored cells represent the data. A chart can consist of one category or several categories. Multiple waffle charts can be put together to show a comparison between different charts.
Buy Me a Coffee? Your support is much appreciated!
PayPal Me: https://www.paypal.me/jiejenn/5
Venmo: @Jie-Jenn
Source Code:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.font_manager as font_manager
'''
Step 1. Setting up the data
categories values
0 Facebook 2701
1 YouTube 2000
2 WhatsApp 2000
3 Facebook Messenger 1300
'''
data = {
'categories': ['YouTube', 'Facebook', 'WhatsApp', 'Facebook Messenger'],
'values': [2000, 2701, 2000, 1300]
}
df = pd.DataFrame(data)
df.sort_values(by=['values'], axis=0, ascending=False, inplace=True)
df.reset_index(drop=True, inplace=True)
'''
Step 2. set waffle size
'''
waffle_width = 20 # column number
waffle_height = 7 # row number
companies = df['categories']
values = df['values']
'''
Step 3.1 Calculuate item proportion
'''
proportions = [value/sum(values) for value in values]
'''
Step 3.2 Calculuate total blocks/chunks
'''
total_blocks = waffle_width * waffle_height
'''
Step 3.3 Calculate chunk blocks
'''
blocks_per_chunk = [round(proportion * total_blocks) for proportion in proportions]
'''
Step 4. Generate matrix table
20 * 7
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
'''
matrix_table = np.zeros((waffle_height, waffle_width))
# 1, 2, 3, 4
'''
[[1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4.]
[1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4.]
[1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4.]
[1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4.]
[1. 1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4.]
[1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4. 4.]
[1. 1. 1. 1. 1. 1. 2. 2. 2. 2. 2. 3. 3. 3. 3. 3. 4. 4. 4. 4.]]
'''
company_identifier = 0
block_index = 0
for col in range(waffle_width):
for row in range(waffle_height):
block_index += 1
if block_index > sum(blocks_per_chunk[0:company_identifier]):
company_identifier += 1
matrix_table[row, col] = company_identifier
'''
Step 5. Graph the waffle chart
'''
fig, axes = plt.subplots(figsize=(15, 7)) # width, height
color_map_style = plt.cm.summer
matshow = axes.matshow(matrix_table, cmap=color_map_style)
# graph axes object
ax = plt.gca()
# inserting the minor ticks
ax.set_xticks(np.arange(-.5, waffle_width, 1), minor=True)
ax.set_yticks(np.arange(-.5, waffle_height, 1), minor=True)
# apply gridlines
ax.grid(which='minor', color='w', linestyle='-', linewidth=2)
ax.set_title('My Waffle Chart', fontdict={'fontsize': 22, 'fontweight': 'medium'})
plt.xticks([])
plt.yticks([])
'''
Step 6. Insert a legend
'''
legend = []
for indx, company_name in enumerate(companies):
label_text = '{1}: ({0})'.format(values[indx], company_name)
color_value = color_map_style(int(indx+1)/len(companies))
legend.append(mpatches.Patch(color=color_value, label=label_text))
font = font_manager.FontProperties(
family='Comic Sans MS',
weight='bold',
style='normal',
size=14
)
plt.legend(
handles=legend,
loc='lower center',
ncol=len(companies),
prop=font,
bbox_to_anchor=(0.02, -.15, 0.95, 0.7) # x, y, width, height
)
plt.show()
