This example demonstrates the implementation of a custom `.BoxStyle`.
Custom `.ConnectionStyle`\s and `.ArrowStyle`\s can be similarly defined.

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


###############################################################################
# Custom box styles can be implemented as a function that takes arguments
# specifying both a rectangular box and the amount of "mutation", and
# returns the "mutated" path.  The specific signature is the one of
# ``custom_box_style`` below.
#
# Here, we return a new path which adds an "arrow" shape on the left of the
# box.
#
# The custom box style can then be used by passing
# ``bbox=dict(boxstyle=custom_box_style, ...)`` to `.Axes.text`.


def custom_box_style(x0, y0, width, height, mutation_size):
    """
    Given the location and size of the box, return the path of the box around
    it.
    Rotation is automatically taken care of.
    Parameters
    ----------
    x0, y0, width, height : float
        Box location and size.
    mutation_size : float
        Mutation reference scale, typically the text font size.
    """
    # padding
    mypad = 0.3
    pad = mutation_size * mypad
    # width and height with padding added.
    width = width + 2 * pad
    height = height + 2 * pad
    # boundary of the padded box
    x0, y0 = x0 - pad, y0 - pad
    x1, y1 = x0 + width, y0 + height
    # return the new path
    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))


###############################################################################
# Likewise, custom box styles can be implemented as classes that implement
# ``__call__``.
#
# The classes can then be registered into the ``BoxStyle._style_list`` dict,
# which allows specifying the box style as a string,
# ``bbox=dict(boxstyle="registered_name,param=value,...", ...)``.
# Note that this registration relies on internal APIs and is therefore not
# officially supported.


class MyStyle:
    """A simple box."""

    def __init__(self, pad=0.3):
        """
        The arguments must be floats and have default values.
        Parameters
        ----------
        pad : float
            amount of padding
        """
        self.pad = pad
        super().__init__()

    def __call__(self, x0, y0, width, height, mutation_size):
        """
        Given the location and size of the box, return the path of the box
        around it.
        Rotation is automatically taken care of.
        Parameters
        ----------
        x0, y0, width, height : float
            Box location and size.
        mutation_size : float
            Reference scale for the mutation, typically the text font size.
        """
        # padding
        pad = mutation_size * self.pad
        # width and height with padding added
        width = width + 2.*pad
        height = height + 2.*pad
        # boundary of the padded box
        x0, y0 = x0 - pad, y0 - pad
        x1, y1 = x0 + width, y0 + height
        # return the new path
        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  # Register the custom style.

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"]  # Unregister it.

plt.show()

Related articles

connection style

When creating an annotation using `~.Axes.annotate`, the arrow shape can be controlled via the *connectionstyle* parameter of *arrowprops*. For further details see the description of `.FancyArrowPatch`.

matplotlib connect

ConnectionPatch` can be used to draw a line (possibly with arrow head) between points defined in different coordinate systems and/or axes.

annotate tex arrow

import numpy as np import matplotlib.pyplot as plt # Fixing random state for reproducibility np.random.seed(19680801)

matplotlib annotate explain

import matplotlib.pyplot as plt import matplotlib.patches as mpatches fig, axs = plt.subplots(2, 2) x1, y1 = 0.3, 0.3 x2, y2 = 0.7, 0.7

matplotlib anchored box04

from matplotlib.patches import Ellipse import matplotlib.pyplot as plt from matplotlib.offsetbox import (AnchoredOffsetbox, DrawingArea, HPacker, TextArea)

sanic request stream

from sanic import Sanic from sanic.blueprints import Blueprint from sanic.response import stream, text from sanic.views import HTTPMethodView from sanic.views import stream as stream_decorator

amending request object

from random import randint from sanic import Sanic from sanic.response import text app = Sanic("Example")

authorized sanic

# -*- coding: utf-8 -*- from functools import wraps from sanic import Sanic from sanic.response import json

sanic blueprints

from sanic import Blueprint, Sanic from sanic.response import file, json app = Sanic("Example") blueprint = Blueprint("bp_example", url_prefix="/my_blueprint") blueprint2 = Blueprint("bp_example2", url_prefix="/my_blueprint2")

fastapi request directly

from fastapi import FastAPI, Request app = FastAPI() @app.get("/items/{item_id}") def read_root(item_id: str, request: Request):