Python matplotlib.pyplot.annotate中箭头的控制角度
下面截图中的注释箭头不是直的,这让我抓狂。我错过了什么?我怀疑这与我指定xy和xytext位置的方式有关,但它们都有相同的y 这就是我指定注释的方式: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,
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'
。你确定你不是指垂直对齐吗?哦,现在我明白你的意思了。对不起。我更新了答案。