Matplotlib 中的自定义框样式

Beginner

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

简介

Matplotlib 是一个用于 Python 编程语言及其数值数学扩展 NumPy 的绘图库。Matplotlib 的特性之一是能够创建自定义的框样式。

在本实验中,你将学习如何在 Matplotlib 中实现自定义框样式。你将学习如何将自定义框样式创建为函数和类。你还将学习如何向 Matplotlib 注册自定义框样式。

虚拟机使用提示

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

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

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

将自定义框样式实现为函数

自定义框样式可以实现为函数,这些函数接受指定矩形框和“变形”量的参数,并返回“变形”后的路径。在这里,我们将实现一种自定义框样式,它返回一个新路径,该路径在框的左侧添加一个“箭头”形状。

import matplotlib.pyplot as plt
from matplotlib.patches import BoxStyle
from matplotlib.path import Path

def custom_box_style(x0, y0, width, height, mutation_size):
    """
    给定框的位置和大小,返回围绕它的框的路径。

    旋转会自动处理。

    参数
    ----------
    x0, y0, width, height : float
        框的位置和大小。
    mutation_size : float
        变形参考比例,通常是文本字体大小。
    """
    ## 填充
    mypad = 0.3
    pad = mutation_size * mypad
    ## 添加填充后的宽度和高度。
    width = width + 2 * pad
    height = height + 2 * pad
    ## 填充后框的边界
    x0, y0 = x0 - pad, y0 - pad
    x1, y1 = x0 + width, y0 + height
    ## 返回新路径
    return Path([(x0, y0),
                 (x1, y0), (x1, y1), (x0, y1),
                 (x0-pad, (y0+y1)/2), (x0, y0),
                 (x0, y0)],
                closed=True)

fig, ax = plt.subplots(figsize=(3, 3))
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
        bbox=dict(boxstyle=custom_box_style, alpha=0.2))
plt.show()

将自定义框样式实现为类

自定义框样式也可以实现为实现了 __call__ 方法的类。然后可以将这些类注册到 BoxStyle._style_list 字典中,这样就可以将框样式指定为字符串,即 bbox=dict(boxstyle="已注册的名称,参数=值,...",...)

class MyStyle:
    """一个简单的框。"""

    def __init__(self, pad=0.3):
        """
        参数必须是浮点数且有默认值。

        参数
        ----------
        pad : float
            填充量
        """
        self.pad = pad
        super().__init__()

    def __call__(self, x0, y0, width, height, mutation_size):
        """
        给定框的位置和大小,返回围绕它的框的路径。

        旋转会自动处理。

        参数
        ----------
        x0, y0, width, height : float
            框的位置和大小。
        mutation_size : float
            变形的参考比例,通常是文本字体大小。
        """
        ## 填充
        pad = mutation_size * self.pad
        ## 添加填充后的宽度和高度
        width = width + 2.*pad
        height = height + 2.*pad
        ## 填充后框的边界
        x0, y0 = x0 - pad, y0 - pad
        x1, y1 = x0 + width, y0 + height
        ## 返回新路径
        return Path([(x0, y0),
                     (x1, y0), (x1, y1), (x0, y1),
                     (x0-pad, (y0+y1)/2.), (x0, y0),
                     (x0, y0)],
                    closed=True)


BoxStyle._style_list["angled"] = MyStyle  ## 注册自定义样式。

fig, ax = plt.subplots(figsize=(3, 3))
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
        bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2))

del BoxStyle._style_list["angled"]  ## 取消注册。

plt.show()

向 Matplotlib 注册自定义框样式

一旦你将自定义框样式实现为类,就可以向 Matplotlib 注册它。这样你就可以将框样式指定为字符串,即 bbox=dict(boxstyle="已注册的名称,参数=值,...",...)

BoxStyle._style_list["angled"] = MyStyle  ## 注册自定义样式。

使用自定义框样式

一旦你实现并注册了自定义框样式,就可以在 Axes.text 中使用它。

fig, ax = plt.subplots(figsize=(3, 3))
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
        bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2))

总结

在本实验中,你学习了如何在 Matplotlib 中实现自定义框样式。你学习了如何将自定义框样式创建为函数和类。你还学习了如何向 Matplotlib 注册自定义框样式以及如何在 Axes.text 中使用它。