简体   繁体   English

将matplotlib矩形边缘设置为指定宽度之外?

[英]Set matplotlib rectangle edge to outside of specified width?

Is there a way to specify the edge for matplotlib's Rectangle patch so that the border is outside the domain specified? 有没有一种方法可以为matplotlib的Rectangle修补程序指定边缘,以使边框位于指定的域之外? In photoshop, this is would be called "stroke position", for example. 例如,在photoshop中,这将称为“笔划位置”。 Allow me to illustrate with an example: 请允许我举例说明:

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()

This yields the following: 这将产生以下结果:

在此处输入图片说明

However, if modified the above as follows 但是,如果对上述内容进行如下修改

ax.add_patch( Rectangle((0.5, 0.5), 2, 2, fc='none', ec='r', lw=10) )

I obtain the figure: 我得到图:

在此处输入图片说明

As you can see, the edge is center-positioned along the border of the domain of the Rectangle object, and so bleeds into this domain. 如您所见,边缘沿Rectangle对象的域的边界居中放置,因此会渗入该域。 Is it possible to force the edge border to be strictly outside the Rectangle's domain? 是否可以强制将边缘边界严格限制在Rectangle的域之外?

You may use an AnnotationBbox inside of which an AuxTransformBox is placed. 您可以使用AnnotationBbox ,并在其中放置AuxTransformBox This AuxTransformBox would contain a proxy rectangle of the desired size. AuxTransformBox将包含所需大小的代理矩形。 This can be made invisible (eg fc='none', ec='none' ). 可以使它不可见(例如, fc='none', ec='none' )。 Its only function is to scale the AuxTransformBox to the right size. 它的唯一功能是将AuxTransformBox到合适的大小。 Now the AnnotationBbox can be given a border of some large linewidth. 现在可以给AnnotationBbox一个较大的线宽边框。 If it is sitting tight against the AuxTransformBox the border will only start where the AuxTransformBox ends. 如果它紧靠AuxTransformBox则边框仅在AuxTransformBox结束的AuxTransformBox开始。 To let the border fit tightly, one can set the padding pad to half the linewidth of the border. 为了使边框紧密贴合,可以将填充pad设置为边框线宽的一半。 Since padding is given in units of fontsize, it is the fontsize which needs to be set to the linewidth and the padding to 0.5, pad=0.5,fontsize=linewidth . 由于填充是以fontsize为单位给出的,因此需要将fontsize设置为线宽,将padding设置为0.5, pad=0.5,fontsize=linewidth Note that it appears that a slightly larger padding of 0.52 looks nicer on the plot; 请注意,在图上似乎稍微大一点的填充0.52看起来更好; in any case this can be adjusted to one's liking. 在任何情况下都可以根据自己的喜好进行调整。

Sounds complicated, but the code is copy and pastable to be used anywhere a Rectangle would usually be used. 听起来很复杂,但是代码是可复制且可粘贴的,可以在通常使用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()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM