Matplotlib:避免注释并勾选 y_tick 标签重叠

Matplotlib: Avoid annotations and tick y_tick labels overlapping

我回答了几个问题,但 none 似乎解决了注释与 y 刻度标签重叠的问题。我找到了一个很好的代码,可以防止注释相互重叠,但没有刻度标签。

我的问题其实很简单。我使用以下几行来创建我粘贴在它们下方的图表。我使用 annotate 来显示这两行的最后一个值是什么。我根据最后一个值占y轴总范围的比例来设置标注的位置。它工作得很好,除非注释与刻度标签重叠。这没什么大不了的,但在报告中包含图表时看起来不太好。

这是代码——我省略了操作数据的行:

x = MERVAL.index[(MERVAL.index >= '2014-01-01')]
y1 = MERVAL['MERVAL'][(MERVAL.index >= '2014-01-01')]
y2 = MERVAL['MERVAL_USD'][(MERVAL.index >= '2014-01-01')]
last_date = MERVAL.tail(1).index
right_limit = last_date + datetime.timedelta(days=30)
months = mdates.MonthLocator(1)
monthsFmt = mdates.DateFormatter('%m/%Y')
datemin = datetime.datetime.strptime('01/01/2014', '%m/%d/%Y')
f, ax = plt.subplots()
ax.plot(x,y1, color='b', linewidth=1, label='MERVAL')
ax2 = ax.twinx()
ax2.plot(x,y2, color='r', linewidth=1, label='MERVAL in USD')
ax.set_title('MERVAL',fontsize=20,color='green')
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(monthsFmt)
ax.set_xlim(left=datemin, right=right_limit)
ax2.set_xlim(left=datemin, right=right_limit)
ax.grid(axis='x', linestyle=':')
ax.legend(loc=(0.01,0.9))
ax2.legend(loc=(0.01,0.8))
bottom, top = ax.get_ylim()
bottom1, top1 = ax2.get_ylim()
MERVAL_last_price = MERVAL.iloc[-1,0]
MERVAL_USD_last_price = MERVAL.iloc[-1,1]
ax.annotate(str(MERVAL.iloc[-1,0].round(2)), xy=(0,(MERVAL.iloc[-1,0])), xytext=(-0.13 ,((MERVAL_last_price - bottom) / (top - bottom))), xycoords='axes fraction', color='b', annotation_clip=False)
ax2.annotate(str(MERVAL.iloc[-1,1].round(2)), xy=(1,(MERVAL.iloc[-1,1])), xytext=(1.01,((MERVAL_USD_last_price - bottom1) / (top1 - bottom1))), xycoords='axes fraction',color='r', annotation_clip=False)
plt.show()

这是图表。以黄色突出显示我要修复的内容:

如以下评论所述,我希望红色标签位于勾号标签上方(最好是因为它的数字较大)或下方。我知道如何把它带到最右边或最左边。我也知道如何手动向上或向下移动它。有没有办法让 Matplotlib 检查它是否与刻度标签重叠并自动向上或向下移动?

谢谢

我认为用我根据上述评论找到的解决方案来完成 post 是个好主意。我选择了 Jody Klymak 评论中的第三个选项。

我添加了几行来查找 y_ticks 是什么,删除最后一个值周围特定范围内的任何刻度,最后设置新的 y_ticks.

更新代码:

x = MERVAL.index[(MERVAL.index >= '2014-01-01')]
y1 = MERVAL['MERVAL'][(MERVAL.index >= '2014-01-01')]
y2 = MERVAL['MERVAL_USD'][(MERVAL.index >= '2014-01-01')]
last_date = MERVAL.tail(1).index
right_limit = last_date + datetime.timedelta(days=30)
months = mdates.MonthLocator(1)
monthsFmt = mdates.DateFormatter('%m/%Y')
datemin = datetime.datetime.strptime('01/01/2014', '%m/%d/%Y')
f, ax = plt.subplots()
ax.plot(x,y1, color='b', linewidth=1, label='MERVAL')
ax2 = ax.twinx()
ax2.plot(x,y2, color='r', linewidth=1, label='MERVAL in USD')
ax.set_title('MERVAL',fontsize=20,color='green')
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(monthsFmt)
ax.set_xlim(left=datemin, right=right_limit)
ax2.set_xlim(left=datemin, right=right_limit)
ax.grid(axis='x', linestyle=':')
ax.legend(loc=(0.01,0.9))
ax2.legend(loc=(0.01,0.8))
bottom, top = ax.get_ylim()
bottom1, top1 = ax2.get_ylim()
MERVAL_last_price = MERVAL.iloc[-1,0]
MERVAL_USD_last_price = MERVAL.iloc[-1,1]
ax.annotate(str(MERVAL.iloc[-1,0].round(2)), xy=(0,(MERVAL.iloc[-1,0])), xytext=(-0.13 ,((MERVAL_last_price - bottom) / (top - bottom))), xycoords='axes fraction', color='b', annotation_clip=False)
ax2.annotate(str(MERVAL.iloc[-1,1].round(2)), xy=(1,(MERVAL.iloc[-1,1])), xytext=(1.01,((MERVAL_USD_last_price - bottom1) / (top1 - bottom1))), xycoords='axes fraction',color='r', annotation_clip=False)
loc = ax2.get_yticks()
space = loc[1] - loc[0]
print(space)
new_loc = list()
for x in loc:
    if x <= MERVAL.iloc[-1,1] + space / 2 and x >= MERVAL.iloc[-1,1] - space / 2:
        new_loc.append('')
    else:
        new_loc.append(x)
ax2.set_yticklabels(new_loc)
plt.show()

更新图表: