[Python] Annotate lines without overlapping

Discussão em 'Python' iniciado por Stack, Junho 4, 2025.

  1. Stack

    Stack Membro Participativo

    I would like to plot numerous lines and caption them with an annotation. However, due to the number of graphs and lines, I need to automatically position my annotations without overlapping other annotations or lines. I have tested the adjustText module without success. The textalloc module seems more promising. I use the following code :

    import textalloc as ta
    import numpy as np
    import matplotlib.pyplot as plt

    # Generate data
    x = np.linspace(0, 10, 500)
    y1 = np.sin(x)
    y2 = np.cos(x)
    y3 = np.sin(x + np.pi/4)

    # Create plot
    fig, ax = plt.subplots()
    ax.plot(x, y1, label='sin(x)', color='blue')
    ax.plot(x, y2, label='cos(x)', color='green')
    ax.plot(x, y3, label='sin(x + π/4)', color='red')

    # Choose a label position near the right end but not exactly at the end (to leave space)
    idx_label = np.abs(x - 9).argmin()

    # Define labels and their corresponding y-values
    curves = [y1, y2, y3]
    labels = ['sin(x)', 'cos(x)', 'sin(x + π/4)']
    colors = ['blue', 'green', 'red']

    # Set x positions (same for all) and extract corresponding y values
    x_pos = [x[idx_label]] * len(curves)
    y_pos = [y[idx_label] for y in curves]

    # Allocate text labels using textalloc to avoid overlap
    texts = ta.allocate(
    ax,
    x_pos, y_pos,
    labels,
    textsize=10,
    x_scatter=x+x+x,
    y_scatter=y1+y3+y2, # background data to help avoid collisions
    linewidth=0.5,
    )

    # Final plot adjustments
    ax.set_title("Auto-placed Labels Without Overlap")
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.grid(True)
    plt.tight_layout()
    plt.show()


    I get the following result :

    [​IMG]

    However, there are overlaps between annotations and the other lines. In addition, in the code I've set the x-coordinate of the point that's annotated, but I'd rather this position be decided automatically according to the place on the graph. How can I do that ?

    Continue reading...

Compartilhe esta Página