PyWaffle简介
PyWaffle是一个基于Matplotlib的Python库,用于创建华夫图(Waffle Chart)。华夫图是一种数据可视化工具,类似于饼图,用于表示部分与整体之间的关系,但它通过网格形式展现数据,更加直观和易于理解。

这个库依赖于Matplotlib库来绘制图片,并且支持Python 3.5及更高版本,确保了广泛的应用兼容性。通过简单的参数配置,如rows(行数)、columns(列数)以及values(数值),PyWaffle即可生成美观且信息量大的瓦片图。此外,颜色、标签、图例等细节均可定制化,满足多样化的视觉需求。
PyWaffle的特点
- 开源与兼容性:
- PyWaffle遵循MIT协议,是一个完全开源的项目。
 - 它支持Python 3.5+版本,并依赖于Matplotlib库,确保了广泛的应用兼容性。
 
 - 简洁的API设计:
- PyWaffle定义了一个Waffle类,作为matplotlib的Figure构造器的一个扩展,允许直接通过pyplot.figure调用,无缝融合到现有的数据可视化流程中。
 - 通过简单的参数配置如rows(行数)、columns(列数)以及values(值),即可生成美观且信息量大的瓦片图。
 
 - 高度可定制:
- PyWaffle提供了丰富的自定义选项,包括颜色方案、图表尺寸、布局样式等,可以满足多样化的视觉需求。
 - 用户可以自定义每个类别的颜色、标签、图例等,使图表更加个性化。
 
 - 直观展示比例:
- 华夫饼图的排列天然适合展示各类比例数据,尤其当数值范围广、分类多时更为明显。
 - 通过方格的数量和颜色,用户可以直观地理解不同类别之间的比例关系。
 
 - 广泛的应用场景:
- PyWaffle适用于市场分析、销售业绩展示、项目管理等多种场景。
 - 在市场分析中,可以迅速反映出不同产品线或区域的销售额占比;在项目管理中,可以监控不同任务的完成进度。
 
 
PyWaffle的使用
安装PyWaffle
在使用PyWaffle之前,你需要先安装它。可以使用以下命令通过pip进行安装:pip install pywaffle
class pywaffle.waffle.Waffle(*args, **kwargs)
参数说明:
- values (list|dict|pandas.Series) – 每个类别的数值。如果是字典,键将用作标签。
 - rows (int) – 华夫图的行数。
 - columns (int) – 华夫图的列数。行和列至少需要一个。如果传递了行或列中的一个,则另一个参数将通过数值的绝对值自动计算。如果同时传递了行和列,则块数量是固定的,并从缩放后的值中计算块数量。
 - colors (list[str]|tuple[str], optional) – 每个类别的颜色列表。其长度应与值相同。默认值来自Set2色图。
 - labels (list[str]|tuple[str], optional) – 每个类别的名称。如果values是字典,则此参数将被值的键替代。
 - legend (dict, optional) – Matplotlib pyplot.legend的参数,以字典形式提供。例如:{‘loc’:”, ‘bbox_to_anchor’:(,), …}。完整参数列表见legend。
 - interval_ratio_x (float, optional) – 块之间水平距离与块宽度的比率。[默认2]
 - interval_ratio_y (float, optional) – 块之间垂直距离与块高度的比率。[默认2]
 - block_aspect_ratio (float, optional) – 块宽与高的比率。[默认1]
 - cmap_name (str, optional) – 默认颜色的色图名称,如果未指定颜色。完整列表见colormaps_reference。[默认‘Set2’]
 - title (dict, optional) – Matplotlib axes.Axes.set_title的参数,以字典形式提供。例如:{‘label’:”, ‘fontdict’:{}, ‘loc’:”}。完整参数列表见title。
 - characters – 字符串中的一个字符或每个类别的字符列表。[默认None]
 - font_size – FontAwesome图标的字体大小。默认大小不是固定的,取决于块大小。可以是相对值(如‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’)或绝对字体大小。
 - font_file – 自定义字体文件的路径。
 - icons (str|list[str]|tuple[str], optional) – FontAwesome的图标名称。如果是字符串,则所有类别使用相同的图标;如果是图标的列表或元组,长度应与值相同。FontAwesome的完整列表见FontAwesome。[默认None]
 - icon_style (str|list[str]|tuple[str], optional) – 要使用的图标样式。FontAwesome图标通过样式和图标名称找到图标。样式可以是‘brands’, ‘regular’和‘solid’。详细信息见FontAwesome Cheatsheet。如果是字符串,则在给定样式内搜索图标。如果是列表或元组,长度应与值相同,表示每个图标的样式。[默认‘solid’]
 - icon_size (int|str, optional) – FontAwesome图标的字体大小。已弃用!请使用font_size。默认大小不是固定的,取决于块大小。可以是相对值(如‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’)或绝对字体大小。
 - icon_legend (bool, optional) – 是否在图例中使用图标而不是颜色条。[默认False]
 - plot_anchor (str, optional) – 子图的对齐方式。{‘C’, ‘SW’, ‘S’, ‘SE’, ‘E’, ‘NE’, ‘N’, ‘NW’, ‘W’}。详细信息见axes.Axes.set_anchor。[默认‘W’]
 - plots (dict, optional) – 子图中Waffle类的位置和参数,以字典形式提供,格式如{pos:{subplot_args:values, }, }。pos可以是三个整数的元组,其中第一个数字是行数,第二个是列数,第三个是子图的索引。pos也可以是3位数字的整数或字符串类型。例如,它接受235或’235’代表在具有J行和K列的网格上的第I个图。注意,对于此格式,所有整数必须小于10。子图的参数与Waffle类参数相同,不包括plots本身。如果未指定子图的任何参数,则使用Waffle类中的相同参数作为默认值。
 - vertical (bool, optional) – 是否垂直绘制图形。[默认False]
 - starting_location (str, optional) – 更改绘制块的起始位置。{‘NW’, ‘SW’, ‘NE’, ‘SE’}。当为’NW’时,表示从左上角开始绘制;’SW’表示从左下角开始绘制;’NE’表示从右上角开始绘制;’SE’表示从右下角开始绘制。[默认‘SW’]
 - rounding_rule (str, optional) – 调整值以适应图表大小时应用的舍入规则。{‘nearest’, ‘floor’, ‘ceil’}。当为’nearest’时,是“四舍五入到最近,偶数优先”的舍入模式;当为’floor’时,舍入到区间的较小端点;当为’ceil’时,舍入到区间的较大端点。[默认‘nearest’]
 
tight (bool|dict, optional) – 设置绘制时是否以及如何调用 .tight_layout。可以是 bool 或具有键 “pad”, “w_pad”, “h_pad”, “rect” 的字典或 None。如果是 bool,则设置是否在绘制时调用 .tight_layout。如果为 None,则使用 autolayout 参数代替。如果是字典,则将其作为 kwargs 传递给 .tight_layout,覆盖默认填充。[默认 True]
基本用法
首先,我们来看一个简单的例子,展示如何使用 PyWaffle 创建一个基本的华夫图。
import matplotlib.pyplot as plt
from pywaffle import Waffle
fig = plt.figure(
    FigureClass=Waffle,
    rows=5,
    columns=10,  # Either rows or columns could be omitted
    values=[30, 16, 4]  # Pass a list of integers to values
)
plt.show()

使用字典中的值和自动调整大小:
data = {'Cat1': 10, 'Cat2': 7, 'Cat3': 9}
fig = plt.figure(
    FigureClass=Waffle,
    rows=5,
    values=data,
    legend={'loc': 'upper left', 'bbox_to_anchor': (1.05, 1)},
)
plt.show()

更多样式设置:
data = {'Car': 58, 'Pickup': 21, 'Truck': 11, 'Motorcycle': 7}
fig = plt.figure(
    FigureClass=Waffle,
    rows=5,
    values=data,
    colors=["#C1D82F", "#00A4E4", "#FBB034", '#6A737B'],
    title={'label': 'Vehicle Sales by Vehicle Type', 'loc': 'left'},
    labels=[f"{k} ({v}%)" for k, v in data.items()],
    legend={'loc': 'lower left', 'bbox_to_anchor': (0, -0.4), 'ncol': len(data), 'framealpha': 0},
    starting_location='NW',
    vertical=True,
    block_arranging_style='snake'
)
fig.set_facecolor('#EEEEEE')
plt.show()

PyWaffle 允许你使用图标而不是方块来表示数据。你可以使用 icons 参数来设置图标,并使用 icon_size 来设置图标大小。
data = {'Car': 58, 'Pickup': 21, 'Truck': 11, 'Motorcycle': 7}
fig = plt.figure(
    FigureClass=Waffle,
    rows=5,
    values=data,
    colors=["#c1d82f", "#00a4e4", "#fbb034", '#6a737b'],
    legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)},
    icons=['car-side', 'truck-pickup', 'truck', 'motorcycle'],
    font_size=12,
    icon_legend=True
)
plt.show()

还可以在一个图中组合多个华夫图。只需在 plots 字典中添加多个子图配置即可。
import pandas as pd
data = pd.DataFrame(
{
'labels': ['Car', 'Truck', 'Motorcycle'],
'FactoryA': [32384, 13354, 5245],
'FactoryB': [22147, 6678, 2156],
'FactoryC': [8932, 3879, 896],
},
).set_index('labels')
# A glance of the data:
# FactoryA FactoryB FactoryC
# labels
# Car 27384 22147 8932
# Truck 7354 6678 3879
# Motorcycle 3245 2156 1196
fig = plt.figure(
FigureClass=Waffle,
plots={
311: {
'values': data['FactoryA']/1000, # Convert actual number to a reasonable block number
'labels': [f"{k} ({v})" for k, v in data['FactoryA'].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['FactoryB']/1000,
'labels': [f"{k} ({v})" for k, v in data['FactoryB'].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['FactoryC']/1000,
'labels': [f"{k} ({v})" for k, v in data['FactoryC'].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=(6, 5)
)
fig.suptitle('Vehicle Production by Vehicle Type', fontsize=14, fontweight='bold')
fig.supxlabel('1 block = 1000 vehicles', fontsize=8, x=0.14)
fig.set_facecolor('#EEEDE7')
plt.show()

参考链接:



