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 : 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...