创建一个帽形图

Beginner

This tutorial is from open-source community. Access the source code

简介

在本实验中,我们将学习如何使用 Matplotlib 库在 Python 中创建一个帽形图。帽形图是堆叠柱状图的一种变体,其中每个柱子都是帽形。我们将使用一个按游戏数量和玩家分类的分数数据集来创建该图表。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会立即为你解决问题。

导入库

在这一步中,我们将导入创建帽形图所需的库。

import matplotlib.pyplot as plt
import numpy as np

定义帽形图函数

在这一步中,我们将定义一个创建帽形图的函数。该函数接受以下参数:

  • ax:要绘制图形的坐标轴。
  • xlabels:要在 x 轴上显示的类别名称。
  • values:数据值。行是组,列是类别。
  • group_labels:图例中显示的组标签。
def hat_graph(ax, xlabels, values, group_labels):
    """
    创建一个帽形图。

    参数
    ----------
    ax : matplotlib.axes.Axes
        要绘制图形的坐标轴。
    xlabels : list of str
        要在 x 轴上显示的类别名称。
    values : (M, N) 类似数组
        数据值。
        行是组 (len(group_labels) == M)。
        列是类别 (len(xlabels) == N)。
    group_labels : list of str
        图例中显示的组标签。
    """

    def label_bars(heights, rects):
        """在每个柱子顶部附加一个文本标签。"""
        for height, rect in zip(heights, rects):
            ax.annotate(f'{height}',
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, 4),  ## 4 个点的垂直偏移。
                        textcoords='offset points',
                        ha='center', va='bottom')

    values = np.asarray(values)
    x = np.arange(values.shape[1])
    ax.set_xticks(x, labels=xlabels)
    spacing = 0.3  ## 帽形组之间的间距
    width = (1 - spacing) / values.shape[0]
    heights0 = values[0]
    for i, (heights, group_label) in enumerate(zip(values, group_labels)):
        style = {'fill': False} if i == 0 else {'edgecolor': 'black'}
        rects = ax.bar(x - spacing/2 + i * width, heights - heights0,
                       width, bottom=heights0, label=group_label, **style)
        label_bars(heights, rects)

准备数据

在这一步中,我们将初始化标签和一个 NumPy 数组。我们要确保数组中有 N 个值对应的 N 个标签。

## 初始化标签和一个 NumPy 数组,确保数组中有
## N 个值对应的 N 个标签
xlabels = ['I', 'II', 'III', 'IV', 'V']
playerA = np.array([5, 15, 22, 20, 25])
playerB = np.array([25, 32, 34, 30, 27])

创建帽形图

在这一步中,我们将使用上一步准备的数据和 hat_graph 函数来创建帽形图。

fig, ax = plt.subplots()
hat_graph(ax, xlabels, [playerA, playerB], ['Player A', 'Player B'])

## 添加一些文本用于标签、标题和自定义 x 轴刻度标签等
ax.set_xlabel('Games')
ax.set_ylabel('Score')
ax.set_ylim(0, 60)
ax.set_title('Scores by number of game and players')
ax.legend()

fig.tight_layout()
plt.show()

完整代码

以下是用 Python 创建帽形图的完整代码。

import matplotlib.pyplot as plt
import numpy as np


def hat_graph(ax, xlabels, values, group_labels):
    """
    创建一个帽形图。

    参数
    ----------
    ax : matplotlib.axes.Axes
        要绘制图形的坐标轴。
    xlabels : list of str
        要在 x 轴上显示的类别名称。
    values : (M, N) 类似数组
        数据值。
        行是组 (len(group_labels) == M)。
        列是类别 (len(xlabels) == N)。
    group_labels : list of str
        图例中显示的组标签。
    """

    def label_bars(heights, rects):
        """在每个柱子顶部附加一个文本标签。"""
        for height, rect in zip(heights, rects):
            ax.annotate(f'{height}',
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, 4),  ## 4 个点的垂直偏移。
                        textcoords='offset points',
                        ha='center', va='bottom')

    values = np.asarray(values)
    x = np.arange(values.shape[1])
    ax.set_xticks(x, labels=xlabels)
    spacing = 0.3  ## 帽形组之间的间距
    width = (1 - spacing) / values.shape[0]
    heights0 = values[0]
    for i, (heights, group_label) in enumerate(zip(values, group_labels)):
        style = {'fill': False} if i == 0 else {'edgecolor': 'black'}
        rects = ax.bar(x - spacing/2 + i * width, heights - heights0,
                       width, bottom=heights0, label=group_label, **style)
        label_bars(heights, rects)


## 初始化标签和一个 NumPy 数组,确保数组中有
## N 个值对应的 N 个标签
xlabels = ['I', 'II', 'III', 'IV', 'V']
playerA = np.array([5, 15, 22, 20, 25])
playerB = np.array([25, 32, 34, 30, 27])

fig, ax = plt.subplots()
hat_graph(ax, xlabels, [playerA, playerB], ['Player A', 'Player B'])

## 添加一些文本用于标签、标题和自定义 x 轴刻度标签等
ax.set_xlabel('Games')
ax.set_ylabel('Score')
ax.set_ylim(0, 60)
ax.set_title('Scores by number of game and players')
ax.legend()

fig.tight_layout()
plt.show()

总结

在这个实验中,我们学习了如何使用 Matplotlib 库在 Python 中创建帽形图。我们定义了一个创建帽形图的函数,准备了数据,并使用hat_graph函数创建了图形。帽形图是堆叠柱状图的一种变体,其中每个柱子都是帽形。我们使用了一个按游戏数量和玩家分类的分数数据集来创建图形。