You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Matplotlib绘制折线图如何避免标注文本与线条重叠

问题描述

我尝试使用x_tn、y_tn列表存储的数值作为(x,y)坐标绘制折线,以seri列表中的序列值作为各数据点的文本标注,简化实现代码如下。但运行后发现标注(1)、(6)等多处位置的文本与折线发生重叠,需要实现标注自动避让折线的通用设置。

原有实现代码:

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as np

x_tn = [0,1,1,2,3,2,2]
y_tn = [0,0,1,2,1,1,0]
seri = [0,1,2,3,4,5,6]

plt.title("Function") 
plt.xlabel("x") 
plt.ylabel("y")

plt.plot(x_tn, y_tn, '-ok')

for x,y,k in zip(x_tn,y_tn,seri):
    label = f"({k})"
    plt.annotate(label,
        (x,y),
        textcoords="offset points",
        xytext=(0,10),
        ha='center')

plt.xticks(np.arange(min(x_tn), max(x_tn)+1, 1))
plt.yticks(np.arange(min(y_tn), max(y_tn)+1, 1))
    
plt.show()

问题运行效果示例:
问题运行效果示例

解决方案

Matplotlib 原生没有提供标注自动避让的通用参数,最通用省事的方案是使用第三方库adjustText,它可以自动迭代调整所有标注的位置,避开折线、数据点、其他标注等图内元素,不需要手动为每个点计算偏移量。

  • 首先安装依赖:执行命令pip install adjustText
  • 改造原有代码:把所有标注对象存入列表,调用adjust_text方法传入标注列表,同时指定标注和数据点的偏移距离、需要避让的图元(折线、散点等)即可。

改造后的可运行代码:

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as np
from adjustText import adjust_text

x_tn = [0,1,1,2,3,2,2]
y_tn = [0,0,1,2,1,1,0]
seri = [0,1,2,3,4,5,6]

plt.title("Function") 
plt.xlabel("x") 
plt.ylabel("y")

line, = plt.plot(x_tn, y_tn, '-ok')
texts = []
for x,y,k in zip(x_tn,y_tn,seri):
    label = f"({k})"
    # 不写死固定偏移,将标注对象统一存储
    texts.append(plt.annotate(label, (x,y), ha='center'))

# 开启自动避让
adjust_text(
    texts,
    # 指定需要避让的图元:折线和对应数据点
    add_objects=[line],
    # 标注距离对应数据点的最小偏移
    min_distance=10,
    # 标注之间、标注和避让图元的最小间距系数
    expand_points=(1.2, 1.2),
    expand_objects=(1.2, 1.2)
)

plt.xticks(np.arange(min(x_tn), max(x_tn)+1, 1))
plt.yticks(np.arange(min(y_tn), max(y_tn)+1, 1))
    
plt.show()

如果不安装第三方库,只能针对当前数据集手动调整每个重叠点的偏移方向,没有通用原生配置可以实现全场景自动避让,更换数据集后需要重新调参,通用性很差。


内容的提问来源于stack exchange,提问作者Rossy Clair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:39:19