matplotlib 刻度标签锚点——右对齐刻度标签(在右侧轴上)和 "clip" 刻度标签的左(西)侧对齐轴

matplotlib tick label anchor -- right align tick labels (on right side axis) and "clip" the left (west) side of the tick labels to the axis

我想将“西”锚点用于双轴(右侧)轴的刻度标签。例如,看下面的图,我希望刻度标签的左侧与右轴对齐。

我尝试了下面的一些方法,但无济于事。

import matplotlib.pyplot as plt
X = [1,2,3]
fig, ax = plt.subplots()
ax.plot(X)
ax.set_ylim([1,3])
ax.set_yticks(X)
axR = ax.twinx()
axR.set_ylim(ax.get_ylim())
axR.set_yticks(ax.get_yticks())
axR.set_yticklabels(['-1.00', '2.00', '3.00'], ha='right')
# axR.set_yticklabels(['-1.00', '2.00', '3.00'], ha='right', bbox_to_anchor='W')
# axR.set_yticklabels(['-1.00', '2.00', '3.00'], ha='right', bbox=dict(bbox_to_anchor='W'))
# bbox can have args from: https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.FancyBboxPatch.html#matplotlib.patches.FancyBboxPatch
fig.show()

所以我遇到了同样的问题,偶然发现了这个问题。我尝试了很多,我基本上决定当标签在右侧左对齐时我需要找到标签的右侧,然后从这一点右对齐它们。

我尝试了一些东西但没有太多经验,所以它并不完美,但它似乎可以通过找到坐标作为 bbox 来工作。我来回转换它以将其作为数组获取(可能是我不知道的更短方式)。然后我把最大的一个的间隙加到间距上。

一些注意事项:我在子图中执行此操作,因此是 ax2。我也已经将轴刻度标签移动到右侧 ax2.yaxis.tick_right()

    r = plt.gcf().canvas.get_renderer()
    coord = ax2.yaxis.get_tightbbox(r)

    ytickcoord = [yticks.get_window_extent() for yticks in ax2.get_yticklabels()]

    inv = ax2.transData.inverted()

    ytickdata = [inv.transform(a) for a in ytickcoord]
    ytickdatadisplay = [ax2.transData.transform(a) for a in ytickdata]
                
    gap = [a[1][0]-a[0][0] for a in ytickdatadisplay]

    for tick in ax2.yaxis.get_majorticklabels():
        tick.set_horizontalalignment("right")

    ax2.yaxis.set_tick_params(pad=max(gap)+1)}

更新:我最近收到了左侧左对齐的类似问题的解决方案。从this solution开始,我相信这可以简化为:

import matplotlib as mpl
import matplotlib.pyplot as plt

fig = plt.figure(figsize =(5,3))
ax = fig.add_axes([0,0,1,1])
plt.plot([0,100,200])
ax.yaxis.tick_right()

# Draw plot to have current tick label positions
plt.draw()
# Read max width of tick labels
ytickcoord = max([yticks.get_window_extent(renderer = plt.gcf().canvas.get_renderer()).width for yticks in ax.get_yticklabels()])
# Change ticks to right aligned
ax.axes.set_yticklabels(ax.yaxis.get_majorticklabels(),ha = "right")
# Add max width of tick labels
ax.yaxis.set_tick_params(pad=ytickcoord+1)

plt.show()
plt.close("all")