Subplots#
Sometimes we would like to show multiple waffle charts in one figure. This is supported through adding subplots. It also helps avoiding duplicated legends, titles and other components.
Let’s say we have sample data as shown below:
import pandas as pd
data = pd.DataFrame(
{
'labels': ['Car', 'Truck', 'Motorcycle'],
'Factory A': [32384, 13354, 5245],
'Factory B': [22147, 6678, 2156],
'Factory C': [8932, 3879, 896],
},
).set_index('labels')
# A glance of the data:
# Factory A Factory B Factory C
# labels
# Car 27384 22147 8932
# Truck 7354 6678 3879
# Motorcycle 3245 2156 1196
To convert the Vehicle Production data above into reasonable block numbers, we can simply pass values like data['Factory A'] / 1000
, and PyWaffle will handle the rounding.
Note that parameter values
also accepts column data in pandas.Series
.
However, unlike values in dict, pandas.Series value does not support auto labeling yet.
To plot multiple subplots in one figure, merge the parameters for each plot to parameter plots
as dict values.
The keys are integers describing the position of the subplot.
It accepts tuple, int and string.
If position is tuple, the format should be like (nrows, ncols, index)
;
if it is int or string, it should be a 3-digit integer like 312
, standing for nrows, ncols, and index in order.
Note that all integers must be less than 10 for the later form to work.
See arguments of matplotlib.pyplot.subplot for more detail.
NOTE: Parameters which are passed outside of
plots
would be applied to all subplots, if they are not specified inplots
. Otherwise, settings inplots
have higher priority.
fig = plt.figure(
FigureClass=Waffle,
plots={
311: {
'values': data['Factory A'] / 1000, # Convert actual number to a reasonable block number
'labels': [f"{k} ({v})" for k, v in data['Factory A'].items()],
'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.05, 1), 'fontsize': 8},
'title': {'label': 'Vehicle Production of Factory A', 'loc': 'left', 'fontsize': 12}
},
312: {
'values': data['Factory B'] / 1000,
'labels': [f"{k} ({v})" for k, v in data['Factory B'].items()],
'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.2, 1), 'fontsize': 8},
'title': {'label': 'Vehicle Production of Factory B', 'loc': 'left', 'fontsize': 12}
},
313: {
'values': data['Factory C'] / 1000,
'labels': [f"{k} ({v})" for k, v in data['Factory C'].items()],
'legend': {'loc': 'upper left', 'bbox_to_anchor': (1.3, 1), 'fontsize': 8},
'title': {'label': 'Vehicle Production of Factory C', 'loc': 'left', 'fontsize': 12}
},
},
rows=5, # Outside parameter applied to all subplots, same as below
cmap_name="Accent", # Change color with cmap
rounding_rule='ceil', # Change rounding rule, so value less than 1000 will still have at least 1 block
figsize=(5, 5)
)
fig.suptitle('Vehicle Production by Vehicle Type', fontsize=14, fontweight='bold')
fig.supxlabel('1 block = 1000 vehicles', fontsize=8, ha='right')