matplotlib 刻度标签锚 - 右对齐刻度标签(在右侧轴上)并将刻度标签的左(西)侧“剪辑”到轴
Posted
技术标签:
【中文标题】matplotlib 刻度标签锚 - 右对齐刻度标签(在右侧轴上)并将刻度标签的左(西)侧“剪辑”到轴【英文标题】: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 【发布时间】:2021-10-29 06:03:38 【问题描述】:我想为 twinx(右侧)轴的刻度标签使用“west”锚点。例如,看下面的图,我希望刻度标签的左侧与右轴对齐。
我尝试了以下几件事,但无济于事。
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()
【问题讨论】:
试试这个:axR.set_yticklabels(['-1.00', '2.00', '3.00'], ha='left')
我特别想要ha='right'
,但要将勾选标签框的左侧“固定”到轴上。
添加这个。 axR.tick_params(axis='y', which='major', pad=-5)
这是你想要达到的目标吗?
这有点笨拙,因为填充必须根据 y 刻度的位数而改变。这里有一个明确的解决方案,那就是改变边界框锚点。这显然是可以实现的,因为在内部某处 matplotlib
可能使用 east
用于左侧 x 轴,north
用于底部 x 轴。
【参考方案1】:
所以我遇到了同样的问题,偶然发现了这个问题。我尝试了很多,我基本上决定当它们在右侧左对齐时我需要找到标签的右侧,然后从这一点开始右对齐。
我尝试了一些东西但没有太多经验,所以它并不完美,但它似乎可以通过将坐标查找为 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")
【讨论】:
感谢您的回答。我在想确切的事情——只需根据最大字符填充以使其适合。我使用pgf
后端,所以可能会使用一些 LaTeX 黑客技术来完成这项工作。
没问题,我在打开大约 30 个标签的情况下确实很沮丧,所以我相信有更清洁的方法可以做到这一点。另一个注意事项我刚刚在使用它的一个案例中出现了一个渲染器错误,这是通过放入 kwarg 来解决的:renderer = r for get_window_extent以上是关于matplotlib 刻度标签锚 - 右对齐刻度标签(在右侧轴上)并将刻度标签的左(西)侧“剪辑”到轴的主要内容,如果未能解决你的问题,请参考以下文章
使用 Seaborn 和 Matplotlib 在热图和线图的共享子图中对齐 x 轴刻度
python matplotlib刻度(含日期刻度处理),标签,网格