Пользовательские стили рамок в Matplotlib

Beginner

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

Введение

Matplotlib - это библиотека для построения графиков для языка программирования Python и его расширения для численных математических вычислений NumPy. Одной из особенностей Matplotlib является возможность создания пользовательских стилей рамок.

В этом практическом занятии вы научитесь реализовывать пользовательские стили рамок в Matplotlib. Вы научитесь создавать пользовательский стиль рамки в виде функции и класса. Также вы научитесь регистрировать пользовательский стиль рамки в Matplotlib.

Советы по работе с ВМ

После запуска ВМ нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к 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.