Python matplotlib.pyplot.annotate中箭头的控制角度

Python matplotlib.pyplot.annotate中箭头的控制角度,python,matplotlib,Python,Matplotlib,下面截图中的注释箭头不是直的,这让我抓狂。我错过了什么?我怀疑这与我指定xy和xytext位置的方式有关,但它们都有相同的y 这就是我指定注释的方式: plt.annotate('Head Motion Cutoff', xy=[data.shape[0], motion_cutoff], xytext=[data.shape[0]+12, motion_cutoff], fontsize=14,

下面截图中的注释箭头不是直的,这让我抓狂。我错过了什么?我怀疑这与我指定xy和xytext位置的方式有关,但它们都有相同的y

这就是我指定注释的方式:

plt.annotate('Head Motion Cutoff',
             xy=[data.shape[0], motion_cutoff],
             xytext=[data.shape[0]+12, motion_cutoff],
             fontsize=14,
             arrowprops=dict(fc='#A9A9A9',
                             ec='#A9A9A9',
                             arrowstyle='simple',
                             shrinkA=4,
                             shrinkB=4))

这是由于文本的垂直对齐(在本例中为“头部运动截断”)。箭头与文本的中心对齐,但默认情况下,文本的基线将设置为您在
xytext
中给出的坐标

最简单的解决方法是将文本的中心设置为
“center”
,这样所有内容都能很好地对齐

例如:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
ax.grid(color='k', alpha=0.5, ls=':')

plt.annotate('Head Motion Cutoff (va=bottom)',
             xy=[0.1, 0.2],
             xytext=[0.4, 0.2],
             fontsize=14,
             arrowprops=dict(fc='#A9A9A9',
                             ec='#A9A9A9',
                             arrowstyle='simple',
                             shrinkA=4,
                             shrinkB=4),
             va='bottom')

plt.annotate('Head Motion Cutoff (va=baseline)',
             xy=[0.1, 0.4],
             xytext=[0.4, 0.4],
             fontsize=14,
             arrowprops=dict(fc='#A9A9A9',
                             ec='#A9A9A9',
                             arrowstyle='simple',
                             shrinkA=4,
                             shrinkB=4),
             va='baseline')

plt.annotate('Head Motion Cutoff (va=top)',
             xy=[0.1, 0.6],
             xytext=[0.4, 0.6],
             fontsize=14,
             arrowprops=dict(fc='#A9A9A9',
                             ec='#A9A9A9',
                             arrowstyle='simple',
                             shrinkA=4,
                             shrinkB=4),
             va='top')

plt.annotate('Head Motion Cutoff (va=center)',
             xy=[0.1, 0.8],
             xytext=[0.4, 0.8],
             fontsize=14,
             arrowprops=dict(fc='#A9A9A9',
                             ec='#A9A9A9',
                             arrowstyle='simple',
                             shrinkA=4,
                             shrinkB=4),
             va='center')

plt.show()

问题在于,默认情况下,箭头连接到文本的中心

但是,您可以使用arrowproperties的
relpos
参数更改箭头连接的位置

plt.annotate(...,  arrowprops=dict(..., relpos=(0, 0)) )
相对位置在文本边界框的坐标中指定

对于底部对齐的文本,可以选择
relpos=(0,0)

对于居中对齐的文本,可以选择
relpos=(0,0.5)

对于顶部对齐的文本,可以选择
relpos=(0,1)

问题是,如果文本不包含任何向下的字符(如此处的
“g”
),则
relpos=(0,0.2)
可能有意义

例如:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, dpi=200)
ax.grid(color='k', alpha=0.5, ls=':')

plt.annotate('Head Motion Cutoff',
         xy=[0.1, 0.8],
         xytext=[60, 0], 
         verticalalignment = "baseline",
         arrowprops=dict(arrowstyle='simple',
                         fc='#A9A9A9', ec='#A9A9A9',
                         shrinkA=4, shrinkB=4,
                         relpos=(0, 0.2)),             
         fontsize=11, 
         textcoords="offset points")



ap = dict(fc='#A9A9A9', ec='#A9A9A9', arrowstyle='simple',
          shrinkA=4, shrinkB=4)

fontsize = 11
aligns = ["bottom", "top", "center"]
positions =  [dict(relpos=(0, 0.)),dict(relpos=(0, 1)),dict(relpos=(0, 0.5))]
kw = dict(fontsize=fontsize, textcoords="offset points")


for i, (align,pos) in enumerate(zip(aligns,positions)):
    ap.update(pos)
    kw.update(dict(arrowprops=ap)) 
    plt.annotate('Head Motion Cutoff (va={})'.format(align),
             xy=[0.1, i*0.2+0.2],
             xytext=[60, 0],
             va=align, ha="left", **kw)

plt.show()

您能否提供允许重现问题的代码?看到了。太好了,谢谢你给我指出“va”选项。非常有用!我也想接受你的答案,但我只能接受其中一个:(.接受另一个是因为在混合中也加入了'relpos',表明我可以选择0、0.5或1以外的其他数字(见图:D)非常感谢!我接受了这个答案,因为它显示了“relpos”和“va”的组合效应。再次感谢,我的强迫症现在稍微减轻了:)为什么在第一个注释中有
horizontalalignment=“bottom”,
?我猜那是打字错误?好吧,但那实际上没什么作用。尝试将其更改为
top
,您会发现它没有任何区别。可以将
['center'|'right'|'left']
作为其值,而不是
'bottom'
。你确定你不是指垂直对齐吗?哦,现在我明白你的意思了。对不起。我更新了答案。