将matplotlib矩形边设置为指定宽度的外部?

Mat*_*ock 9 python matplotlib

有没有办法为matplotlib的Rectangle补丁指定边缘,以便边界在指定的域之外?例如,在photoshop中,这将被称为"笔画位置".请允许我举例说明:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle


# Here's my "image"
X = np.arange(16).reshape(4,4)

# Suppose I want to highlight some feature in the middle boxes.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(X, cmap=plt.cm.gray, interpolation='nearest')
ax.add_patch( Rectangle((0.5, 0.5), 2, 2, fc='none', ec='r') )
plt.show()
Run Code Online (Sandbox Code Playgroud)

这产生以下结果:

在此输入图像描述

但是,如果修改如下

ax.add_patch( Rectangle((0.5, 0.5), 2, 2, fc='none', ec='r', lw=10) )
Run Code Online (Sandbox Code Playgroud)

我得到了这个数字:

在此输入图像描述

如您所见,边缘位于Rectangle对象域边界的中心位置,因此会渗入此域.是否可以强制边缘边界严格位于Rectangle域之外?

Imp*_*est 8

您可以使用放置了an 的AnnotationBbox内部AuxTransformBox。这AuxTransformBox将包含所需大小的代理矩形。这可以不可见(例如fc='none', ec='none')。它唯一的功能是缩放AuxTransformBox到正确的大小。现在AnnotationBbox可以给出一些大线宽的边框。如果它紧紧靠在AuxTransformBox边界上,则只会从AuxTransformBox结束的地方开始。为了让边框紧密贴合,可以将填充设置为边框pad线宽的一半。由于 padding 以 fontsize 为单位给出,因此需要将 fontsize 设置为 linewidth 并将 padding 设置为 0.5, pad=0.5,fontsize=linewidth。请注意,看起来稍微大一点的 0.52 填充在绘图上看起来更好;无论如何,这可以根据自己的喜好进行调整。

听起来很复杂,但代码是可复制和粘贴的,可以在通常使用 Rectangle 的任何地方使用。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.offsetbox import AnnotationBbox, AuxTransformBox


# Here's my "image"
X = np.arange(16).reshape(4,4)

# Suppose I want to highlight some feature in the middle boxes.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(X, cmap=plt.cm.gray, interpolation='nearest', aspect="auto")

linewidth=14
xy, w, h = (0.5, 0.5), 2, 2
r = Rectangle(xy, w, h, fc='none', ec='gold', lw=1)

offsetbox = AuxTransformBox(ax.transData)
offsetbox.add_artist(r)
ab = AnnotationBbox(offsetbox, (xy[0]+w/2.,xy[1]+w/2.),
                    boxcoords="data", pad=0.52,fontsize=linewidth,
                    bboxprops=dict(facecolor = "none", edgecolor='r', 
                              lw = linewidth))
ax.add_artist(ab)


plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明