Python matplotlib:在线宽点和转换之间转换?

Python matplotlib:在线宽点和转换之间转换?,python,matplotlib,Python,Matplotlib,在许多情况下,我发现在图形上放置方轴很方便,这样我就可以轻松地在transAxes单元中工作,而不必担心图形的纵横比。然而,我遇到的一个问题是,当你画一条线时,线宽从路径的任意方向延伸lw/2点。当然,这是正常的、预期的行为,但它会导致一个问题,即如果我试图在某些轴上刻一些东西(并使用边界框中的所有空间),这些线将剪切到轴的边缘。我可以设置clip\u on=False,但这只会使我试图在轴上刻下的图形超出轴的边界。我的问题是-如何在“线宽”规格(以点为单位)和转置单位之间进行转换,以便补偿形状

在许多情况下,我发现在图形上放置方轴很方便,这样我就可以轻松地在
transAxes
单元中工作,而不必担心图形的纵横比。然而,我遇到的一个问题是,当你画一条线时,线宽从路径的任意方向延伸
lw/2
点。当然,这是正常的、预期的行为,但它会导致一个问题,即如果我试图在某些轴上刻一些东西(并使用边界框中的所有空间),这些线将剪切到轴的边缘。我可以设置
clip\u on=False
,但这只会使我试图在轴上刻下的图形超出轴的边界。我的问题是-如何在“线宽”规格(以点为单位)和
转置
单位之间进行转换,以便补偿形状的额外长度/宽度

我已经制定了一个简单的MWE,它应该能够证明我的意思:

"""
MWE demonstrating the cliping of linewidths that are inscribed in axes.
"""
from __future__ import division
from matplotlib.pyplot import figure, show, savefig
from matplotlib.pyplot import Circle
from matplotlib.lines import Line2D

# Make a figure
(fig_w, fig_h) = (7.5, 2.5)
cdpi = 150
fig_aspect = fig_h/fig_w
fig = figure(1, figsize=(fig_w, fig_h), dpi=cdpi)

# Helper functions to center the circles
get_w_from_h = lambda h: h*fig_aspect
get_b_from_h = lambda h: (1-h)/2
get_l_centered = lambda left, span, w: left+(span-w)/2

# Left circle 1 - The line at the center shows that lw is the same number of pixels no matter 
# what transform you use.
l_h = 0.25
l_w = get_w_from_h(l_h);        l_b = get_b_from_h(l_h)
l_l = get_l_centered(0, 1/3, l_w)
l_box = [l_l, l_b, l_w, l_h]

lcax = fig.add_axes(l_box)
lclw = 2.0
lcirc = Circle((0.5, 0.5), 0.5, lw=lclw, color='#FF3932', fill=False, transform=lcax.transAxes)
lline = Line2D([-0.5, 1.5], [0.5, 0.5], lw=lclw*4, color='#FF3932', 
             dashes=[5,1e-14,1e-14, 5], clip_on=False, transform=lcax.transAxes)
lcax.add_patch(lcirc)
lcax.add_line(lline)
lcax.axis('off')

# Left Circle 2
l_h2 = 0.75
l_w2 = get_w_from_h(l_h2);      l_b2 = get_b_from_h(l_h2)
l_l2 = get_l_centered(0, 1/3, l_w2)
l_box2 = [l_l2, l_b2, l_w2, l_h2]

lcax2 = fig.add_axes(l_box2)
lcirc2 = Circle((0.5, 0.5), 0.5, lw=lclw, color='#b20500', fill=False, transform=lcax2.transAxes)
lline2 = Line2D([0.1, 0.9], [0.5, 0.5], lw=lclw*4, color='#b20500', 
             dashes=[1e-14,5,5, 1e-14], transform=lcax2.transAxes)
lcax2.add_patch(lcirc2)
lcax2.add_line(lline2)
lcax2.axis('off')


# Middle circle
m_h = 0.9
m_w = get_w_from_h(m_h);        m_b = get_b_from_h(m_h)
m_l = get_l_centered(1/3, 1/3, m_w)
m_box = [m_l, m_b, m_w, m_h]

mcax = fig.add_axes(m_box)
mclw = 4.0
mcirc = Circle((0.5, 0.5), 0.5, lw=mclw, color='b', fill=False, 
               clip_on=False,
               transform=mcax.transAxes)
mcax.add_patch(mcirc)
mcax.axis('off')

# Right circle 1
r_h = 0.75
r_w = get_w_from_h(r_h);        r_b = get_b_from_h(r_h)
r_l = get_l_centered(2/3, 1/3, r_w)
r_box = [r_l, r_b, r_w, r_h]

rcax = fig.add_axes(r_box, zorder=1)
rclw = 2.0
rcirc = Circle((0.5, 0.5), 0.5, lw=rclw, edgecolor='k', facecolor='#4E4E4E', 
               fill=True, transform=rcax.transAxes)
rcax.add_patch(rcirc)
rcax.axis('off')

# Right circle 2
r_h2 = 0.5
r_w2 = get_w_from_h(r_h2);      r_b2 = get_b_from_h(r_h2)
r_l2 = get_l_centered(2/3, 1/3, r_w2)
r_box2 = [r_l2, r_b2, r_w2, r_h2]

rcax2 = fig.add_axes(r_box2, zorder=2)
rcirc2 = Circle((0.5, 0.5), 0.5, lw=rclw, edgecolor='none', facecolor='#BBBBBB', 
               fill=True, transform=rcax2.transAxes)
rcax2.add_patch(rcirc2)
rcax2.axis('off')

savefig('ClippingMWE.png', transparent=True, dpi=cdpi)
这就产生了这个数字:

根据左圆圈中的比较,无论放置在哪个轴上,线宽似乎总是相同数量的像素(这很有意义)。中心圆是我希望所有圆看起来都像的(没有剪辑),但当然,这个圆实际上比我希望的要宽一些。右侧的圆圈显示剪裁框相对于直线的作用位置。很明显,在轴上刻满圆圈是没有问题的

虽然我也很想知道是否有一个标志或我可以设置的东西来在路径的某一侧画线(例如,在路径的内侧画线,而不是在路径的中心),但我主要感兴趣的是如何从
lw
转换到
transAxes
单位,因为在计算容纳给定大小字体所需的空间量时,我遇到了基本相同的问题