5 Best Ways to Create Waffle Charts in Python Matplotlib

πŸ’‘ Problem Formulation: A waffle chart is a compelling visualization tool that displays parts of a whole in a square grid, where each square represents a percentage point or a proportionate value. For instance, if you wish to represent the market share of different smartphone brands, the input could be a list of brands with their corresponding market shares, and the desired output would be a grid-like chart visually segmenting the market distribution.

Method 1: Utilizing Matplotlib and Numpy

This method involves using a combination of Matplotlib for plotting and Numpy for numerical operations. The function create_waffle_chart() takes the proportions of each category and translates them into a matrix form that Matplotlib can use to create the chart.

Here’s an example:

import matplotlib.pyplot as plt
import numpy as np

def create_waffle_chart(categories, values, height, width, colormap, value_sign=''):
    total_values = sum(values)
    category_proportions = [(float(value) / total_values) for value in values]
    
    total_num_tiles = width * height
    tiles_per_category = [round(proportion * total_num_tiles) for proportion in category_proportions]

    waffle_chart = np.zeros((height, width))
    category_index = 0
    tile_index = 0

    for col in range(width):
        for row in range(height):
            tile_index += 1

            if tile_index > sum(tiles_per_category[0:category_index]):
                category_index += 1       
            
            waffle_chart[row, col] = category_index
    
    fig = plt.figure()
    colormap = plt.cm.coolwarm
    plt.matshow(waffle_chart, cmap=colormap)
    plt.axis('off')
    plt.show()

# Example of usage
category_names = ['Category A', 'Category B', 'Category C']
values = [30, 40, 30]
width = 40
height = 10
create_waffle_chart(category_names, values, height, width, plt.cm.coolwarm)

The output is a waffle chart plot with three different sections corresponding to the categories with different colors.

This code snippet defines the function create_waffle_chart(), which creates a waffle chart based on the proportions of the given categories. It calculates the number of tiles that each category should occupy in the chart, creates a matrix to represent the chart, and then displays the chart using Matplotlib’s functions.

Method 2: Using the PyWaffle Library

PyWaffle is an external library specifically designed for generating waffle charts in Python. It is a wrapper around Matplotlib and simplifies many of the steps needed in the first method. To use PyWaffle, it needs to be installed via pip install pywaffle.

Here’s an example:

from pywaffle import Waffle

fig = plt.figure(
    FigureClass=Waffle, 
    rows=10, 
    values={'Category A': 30, 'Category B': 40, 'Category C': 30},
    colors=("#232066", "#983D3D", "#DCB732"),
    legend={'loc': 'upper left', 'bbox_to_anchor': (1,1)},
    icons='child', icon_size=18, 
    icon_legend=True
)
plt.show()

The output is a visually-pleasing waffle chart representing the given categories and their corresponding values with icons.

This code utilizes PyWaffle to create a waffle chart succinctly. It takes a dictionary of category names and values, and the Waffle class from PyWaffle takes care of dividing the figure into the specified number of rows and columns and filling it with the corresponding sections and colors.

Method 3: Custom Implementation with Patches

In this method, we manually draw a waffle chart using Matplotlib’s patches. This gives us a lot of control over the appearance of each square in the waffle chart and is suited for those who want to fine-tune the chart extensively.

Here’s an example:

import matplotlib.patches as patches

fig = plt.figure()
ax = fig.add_subplot(111)

category_colors = plt.cm.viridis(np.linspace(0, 1, len(values)))
start_pos = 0
for i, (cat, val) in enumerate(zip(category_names, values)):
    ax.add_patch(
        patches.Rectangle((0.05, start_pos), 
                          0.8, 
                          val * height / total_values,
                          edgecolor='white',
                          facecolor=category_colors[i]
                         )
    )
    start_pos += val * height / total_values

plt.axis('off')
plt.show()

The output is a customized waffle chart with individually drawn patches for each category segment, showing distinct sections with different colors.

This snippet uses the patches module from Matplotlib to draw rectangles for each category proportion. The chart is highly customizable and can be fine-tuned for specific aesthetic requirements, but requires more manual setup compared to other methods.

Method 4: Plotting with Squarify

Squarify is a Python library that can create tree maps, which are closely related to waffle charts. With a few adjustments, Squarify can be repurposed to create a waffle-like representation of data.

Here’s an example:

import squarify

normed_values = squarify.normalize_sizes(values, width, height)
rects = squarify.squarify(normed_values, 0, 0, width, height)
colors = [plt.cm.Spectral(i/float(len(category_names))) for i in range(len(category_names))]
squarify.plot(rects, label=category_names, color=colors, pad=True)
plt.axis('off')
plt.show()

The output is a tree map that resembles a waffle chart, where each category is represented by a colored square area proportional to its value.

The code uses the squarify library to normalize the values and calculate the size and positions of the rectangles to be plotted. Then, it uses the plot function from squarify to generate a tree map-like plot that works as a waffle chart with padding between the squares.

Bonus One-Liner Method 5: Plotting With plt.bar

Sometimes, a simple bar chart can be styled to mimic a waffle chart. This one-liner trick uses the plt.bar function to create a faux waffle chart effortlessly.

Here’s an example:

plt.bar(x=range(len(values)), height=values, tick_label=category_names, color=category_colors)
plt.show()

The output is a bar chart styled to give an appearance similar to a waffle chart, but with less granularity and representation accuracy.

The plt.bar function creates a standard bar chart. This approach does not create a true waffle chart but may be a quick workaround for visualizing proportions in a bar-like grid format.

Summary/Discussion

  • Method 1: Utilizing Matplotlib and Numpy. Strengths: Highly customizable and no need for external libraries. Weaknesses: Most complex and involves manual calculations.
  • Method 2: Using the PyWaffle Library. Strengths: Easiest method with a dedicated library. Weaknesses: Requires installation of an external library, and has less flexibility than pure Matplotlib.
  • Method 3: Custom Implementation with Patches. Strengths: Offers fine-grained control over chart appearance. Weaknesses: Requires more manual coding and can be time-consuming.
  • Method 4: Plotting with Squarify. Strengths: Generates aesthetically pleasing charts with minimal effort. Weaknesses: Not an actual waffle chart but a treemap, may not be suitable for all datasets.
  • Method 5: One-Liner with plt.bar. Strengths: Quick and straightforward. Weaknesses: Not a true waffle chart and provides the least accurate representation.