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 – Font Awesome 图标的字体大小。默认大小不是固定的,取决于块大小。可以是相对值(如 ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’)或绝对字体大小。
- font_file – 自定义字体文件的路径。
- icons (str|list[str]|tuple[str], optional) – Font Awesome 的图标名称。如果是字符串,则所有类别使用相同的图标;如果是图标的列表或元组,长度应与值相同。Font Awesome 的完整列表见 Font Awesome。[默认 None]
- icon_style (str|list[str]|tuple[str], optional) – 要使用的图标样式。Font Awesome 图标通过样式和图标名称找到图标。样式可以是 ‘brands’, ‘regular’ 和 ‘solid’。详细信息见 Font Awesome Cheatsheet。如果是字符串,则在给定样式内搜索图标。如果是列表或元组,长度应与值相同,表示每个图标的样式。[默认 ‘solid’]
- icon_size (int|str, optional) – Font Awesome 图标的字体大小。已弃用!请使用 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]
- block_arranging_style (string, optional) – 设置如何排列块。{‘normal’, ‘snake’, ‘new-line’}。如果为 ‘normal’,则逐行绘制块,方向相同。如果为 ‘snake’,则以蛇形模式绘制块。如果为 ‘new-line’,则在绘制每个类别时从新行开始。这仅在只分配了行或列中的一个时有效,并且当 rows 被分配时 vertical=False 或 vertical=True 时有效。[默认 ‘normal’]
基本用法
首先,我们来看一个简单的例子,展示如何使用 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'], '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 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=(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()
参考链接: