matplotlib调用adjust_text时如何将标签推离红色对角参考线
问题场景
现有如下DataFrame:
d = {'a': [2, 3, 4.5], 'b': [3, 2, 5]} df = pd.DataFrame(data=d, index=["val1", "val2","val3"]) print(df)
输出为:
a b val1 2.0 3 val2 3.0 2 val3 4.5 5
使用如下代码绘制散点图、添加y=x红色参考线,并调用adjust_text调整散点标签位置:
fig, ax=plt.subplots(figsize=(10,10)) ax.scatter(df["a"], df["b"],s=1) x1=[0, 2512] y1=[0, 2512] ax.plot(x1,y1, 'r-') ax = plt.gca() ax.set_xlim([0, 10]) ax.set_ylim([0, 10]) TEXTS = [] for idx, names in enumerate(df.index.values): x, y = df["a"].iloc[idx], df["b"].iloc[idx] TEXTS.append(ax.text(x, y, names, fontsize=12)) adjust_text( TEXTS, expand_points=(2.5, 2.5), expand_text=(2.5,2), autoalign="xy", arrowprops=dict(arrowstyle="-", lw=1), ax=ax )
当前运行效果如下,标签会贴近甚至压在红色对角线上,无法实现标签远离对角线的预期排布:
预期排布效果如下:
解决方法
核心原因是adjust_text默认仅对散点、其他文本标签做避让计算,不会主动识别手动绘制的参考线,所以不会主动把标签推离对角线,有两种可直接落地的实现方案:
- 方案1:手动预设标签初始偏移(效果最可控,和预期匹配度最高)
点数量较少时,可直接根据每个点相对于y=x对角线的位置,给标签设置初始偏移方向:对角线上方(b>a)的点标签往左上偏移,对角线下方(b<a)的点标签往右下偏移,后续让adjust_text仅处理标签之间的避让即可,修改后的代码:TEXTS = [] base_offset = 0.3 for idx, names in enumerate(df.index.values): x, y = df["a"].iloc[idx], df["b"].iloc[idx] if y > x: # 线上方点:标签往左上偏移 tx, ty = x - base_offset, y + base_offset else: # 线下方点:标签往右下偏移 tx, ty = x + base_offset, y - base_offset TEXTS.append(ax.text(tx, ty, names, fontsize=12, ha='center', va='center')) adjust_text( TEXTS, expand_points=(1.5, 1.5), expand_text=(1.5,1.5), autoalign="xy", arrowprops=dict(arrowstyle="-", lw=1), ax=ax ) - 方案2:将对角线传入避让对象列表(适合数据量大的场景)
adjust_text提供add_objects参数,支持传入自定义的matplotlib绘图对象作为避让目标,将红色对角线传入后,算法会自动计算位置避开该线,修改代码如下:# 绘制对角线时保存对象引用 diag_line, = ax.plot(x1,y1, 'r-') adjust_text( TEXTS, expand_points=(2.5, 2.5), expand_text=(2.5,2), autoalign="xy", arrowprops=dict(arrowstyle="-", lw=1), ax=ax, add_objects=[diag_line], expand_objects=(1.2, 1.2) # 控制和对角线的避让距离 )
内容的提问来源于stack exchange,提问作者Limmi
相关产品推荐
相关产品推荐

