绘制花式框#

以下示例展示了如何绘制具有不同视觉属性的框 ( FancyBboxPatch ).

import inspect

import matplotlib.pyplot as plt

import matplotlib.patches as mpatch
from matplotlib.patches import FancyBboxPatch
import matplotlib.transforms as mtransforms

框样式#

FancyBboxPatch 支持不同的 BoxStyle .请注意, text 允许通过添加 bbox 参数在文本周围绘制一个框.因此,在以下示例中,您看不到显式的 FancyBboxPatchBoxStyle 调用.

styles = mpatch.BoxStyle.get_styles()
ncol = 2
nrow = (len(styles) + 1) // ncol
axs = (plt.figure(figsize=(3 * ncol, 1 + nrow))
       .add_gridspec(1 + nrow, ncol, wspace=.5).subplots())
for ax in axs.flat:
    ax.set_axis_off()
for ax in axs[0, :]:
    ax.text(.2, .5, "boxstyle",
            transform=ax.transAxes, size="large", color="tab:blue",
            horizontalalignment="right", verticalalignment="center")
    ax.text(.4, .5, "default parameters",
            transform=ax.transAxes,
            horizontalalignment="left", verticalalignment="center")
for ax, (stylename, stylecls) in zip(axs[1:, :].T.flat, styles.items()):
    ax.text(.2, .5, stylename, bbox=dict(boxstyle=stylename, fc="w", ec="k"),
            transform=ax.transAxes, size="large", color="tab:blue",
            horizontalalignment="right", verticalalignment="center")
    ax.text(.4, .5, str(inspect.signature(stylecls))[1:-1].replace(", ", "\n"),
            transform=ax.transAxes,
            horizontalalignment="left", verticalalignment="center")
fancybox demo

用于修改框的参数#

BoxStyle 有额外的参数来配置它们的外观.例如,"round"框可以有 padrounding .

此外, FancyBboxPatch 参数 mutation_scalemutation_aspect 可以缩放框的外观.

def add_fancy_patch_around(ax, bb, **kwargs):
    kwargs = {
        'facecolor': (1, 0.8, 1, 0.5),
        'edgecolor': (1, 0.5, 1, 0.5),
        **kwargs
    }
    fancy = FancyBboxPatch(bb.p0, bb.width, bb.height, **kwargs)
    ax.add_patch(fancy)
    return fancy


def draw_control_points_for_patches(ax):
    for patch in ax.patches:
        patch.axes.plot(*patch.get_path().vertices.T, ".",
                        c=patch.get_edgecolor())


fig, axs = plt.subplots(2, 2, figsize=(8, 8))

# Bbox object around which the fancy box will be drawn.
bb = mtransforms.Bbox([[0.3, 0.4], [0.7, 0.6]])

ax = axs[0, 0]
# a fancy box with round corners. pad=0.1
add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1")
ax.set(xlim=(0, 1), ylim=(0, 1), aspect=1,
       title='boxstyle="round,pad=0.1"')

ax = axs[0, 1]
# bbox=round has two optional arguments: pad and rounding_size.
# They can be set during the initialization.
fancy = add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1")
# The boxstyle and its argument can be later modified with set_boxstyle().
# Note that the old attributes are simply forgotten even if the boxstyle name
# is same.
fancy.set_boxstyle("round,pad=0.1,rounding_size=0.2")
# or: fancy.set_boxstyle("round", pad=0.1, rounding_size=0.2)
ax.set(xlim=(0, 1), ylim=(0, 1), aspect=1,
       title='boxstyle="round,pad=0.1,rounding_size=0.2"')

ax = axs[1, 0]
# mutation_scale determines the overall scale of the mutation, i.e. both pad
# and rounding_size is scaled according to this value.
add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1", mutation_scale=2)
ax.set(xlim=(0, 1), ylim=(0, 1), aspect=1,
       title='boxstyle="round,pad=0.1"\n mutation_scale=2')

ax = axs[1, 1]
# mutation_aspect scales the vertical influence of the parameters (technically,
# it scales the height of the box down by mutation_aspect, applies the box parameters
# and scales the result back up). In effect, the vertical pad is scaled to
# pad * mutation_aspect, e.g. mutation_aspect=0.5 halves the vertical pad.
add_fancy_patch_around(ax, bb, boxstyle="round,pad=0.1", mutation_aspect=0.5)
ax.set(xlim=(0, 1), ylim=(0, 1),
       title='boxstyle="round,pad=0.1"\nmutation_aspect=0.5')

for ax in axs.flat:
    draw_control_points_for_patches(ax)
    # Draw the original bbox (using boxstyle=square with pad=0).
    add_fancy_patch_around(ax, bb, boxstyle="square,pad=0",
                           edgecolor="black", facecolor="none", zorder=10)

fig.tight_layout()


plt.show()
boxstyle=

在非等宽高比的轴上创建视觉上恒定的填充#

由于填充是在框坐标中,即通常是数据坐标,如果轴的宽高比不是 1,则给定的填充会呈现为不同的视觉大小.为了获得视觉上相等的垂直和水平填充,请将 mutation_aspect 设置为轴宽高比的倒数.这可以适当地缩放垂直填充.

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6.5, 5))

# original boxes
bb = mtransforms.Bbox([[-0.5, -0.5], [0.5, 0.5]])
add_fancy_patch_around(ax1, bb, boxstyle="square,pad=0",
                       edgecolor="black", facecolor="none", zorder=10)
add_fancy_patch_around(ax2, bb, boxstyle="square,pad=0",
                       edgecolor="black", facecolor="none", zorder=10)
ax1.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), aspect=2)
ax2.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), aspect=2)


fancy = add_fancy_patch_around(
    ax1, bb, boxstyle="round,pad=0.5")
ax1.set_title("aspect=2\nmutation_aspect=1")

fancy = add_fancy_patch_around(
    ax2, bb, boxstyle="round,pad=0.5", mutation_aspect=0.5)
ax2.set_title("aspect=2\nmutation_aspect=0.5")
aspect=2 mutation_aspect=1, aspect=2 mutation_aspect=0.5

参考

以下函数,方法,类和模块的用法在本例中显示:

  • matplotlib.patches

  • matplotlib.patches.FancyBboxPatch

  • matplotlib.patches.BoxStyle

  • matplotlib.patches.BoxStyle.get_styles

  • matplotlib.transforms.Bbox

  • matplotlib.figure.Figure.text

  • matplotlib.axes.Axes.text

脚本的总运行时间:(0 分 1.300 秒)

Gallery generated by Sphinx-Gallery