是否可以将matplotlib注释锚定到x轴中的数据坐标,但是到y轴的相对位置?

ali*_*i_m 9 python numpy matplotlib coordinate-transformation

我有一个情节,我想用箭头和标签在x轴上注释一个特定的位置:

  • 需要在数据坐标中精确指定箭头尖端的位置.
  • 箭头应该是垂直的,因此箭头钝端(和文本标签)的x坐标也应该精确地指定在数据坐标中.
  • 但是,我希望能够指定箭头的钝端相对于轴边界框的y位置,而不是数据.

我当前的工作解决方案涉及在数据坐标中指定箭头尖端和标签的位置:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.transforms import blended_transform_factory


x = np.random.randn(10000)
r = 3
label = 'foo'
arrowprops = dict(fc='r', ec='k')

def make_example_plot():
    fig, ax = plt.subplots(1, 1)
    ax.hold(True)
    counts, edges, patches = ax.hist(x)
    return fig, ax

fig, ax = make_example_plot()
lo, hi = ax.get_ylim()
ax.annotate(label, xy=(r, 0), xycoords='data',
            xytext=(r, hi * 1.1), textcoords='data', fontsize='xx-large',
            ha='center', va='center', color='r', arrowprops=arrowprops)
ax.set_ylim(0, hi * 1.3)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

无论我如何缩放或平移y轴,我都希望标签保持在y的恒定位置.通过将混合的xy转换传递给ax.text:我可以实现纯文本标签的预期效果:

fig, ax = make_example_plot()
tform = blended_transform_factory(ax.transData, ax.transAxes)
ax.text(r, 0.9, label, fontsize='xx-large', color='r', transform=tform)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果您再现此图然后平移或缩放它,您将看到文本相对于轴边界框在x中移动,但在y中保持固定位置.当然,这仍然不会给我箭头.我希望我可以使用相同的方法ax.annotate,但这似乎不起作用:

fig, ax = make_example_plot()
tform = blended_transform_factory(ax.transData, ax.transAxes)
ax.annotate(label, xy=(r, 0), xycoords='data', transform=tform,
            xytext=(r, 0.9), textcoords='data', fontsize='xx-large',
            ha='center', va='center', color='r', arrowprops=arrowprops)
Run Code Online (Sandbox Code Playgroud)

标签和箭头y = 0.9位于数据坐标中,而不是y轴总高度的90%:

在此输入图像描述

有没有办法分别指定应用于matplotlib.text.Annotation?的x和y变换的参考帧?

tit*_*jan 9

将转换传递给xycoords和textcoords参数而不是transform参数.像这样:

fig, ax = make_example_plot()
tform = blended_transform_factory(ax.transData, ax.transAxes)
ax.annotate(label, xy=(r, 0), xycoords=tform, 
            xytext=(r, 0.9), textcoords=tform, fontsize='xx-large',
            ha='center', va='center', color='r', arrowprops=arrowprops)
Run Code Online (Sandbox Code Playgroud)