matplotlib: labeling of curves

Question:

When I create a plot with many curves it would be convenient to be able to label each curve at the right where it ends.

The result of plt.legend produces too many similar colors and the legend is overlapping the plot.

As one can see in the example below the use of plt.legend is not very effective:

import numpy as np
from matplotlib import pyplot as plt

n=10
x = np.linspace(0,1, n)

for i in range(n):
   y = np.linspace(x[i],x[i], n)
   plt.plot(x, y, label=str(i))
   
plt.legend(loc='upper right')

plt.show()

enter image description here

If possible I would like to have something similar to this plot:

enter image description here

or this:

enter image description here

Asked By: len

||

Answers:

I would recommend the answer suggested in the comments, but another method that gives something similar to your first option (albeit without the exact placement of the legend markers matching the positions of the associated lines) is:

import numpy as np

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

n=10
x = np.linspace(0, 1, n)
labels = [str(i) for i in range(len(x))]

for i in range(n):
    y = np.linspace(x[i], x[i], n)
    ax.plot(x, y, label=labels[i])

h, _ = ax.get_legend_handles_labels()

# sort the legend handles/labels so they are in the same order as the data
hls = sorted(zip(x, h, labels), reverse=True)

ax.legend(
    [ha[1] for ha in hls],  # get handles
    [la[2] for la in hls],  # get labels
    bbox_to_anchor=(1.04, 0, 0.1, 1),  # set box outside of axes
    loc="lower left",
    labelspacing=1.6,  # add space between labels
)

leg = ax.get_legend()

# expand the border of the legend
fontsize = fig.canvas.get_renderer().points_to_pixels(leg._fontsize)
pad = 2 * (leg.borderaxespad + leg.borderpad) * fontsize
leg._legend_box.set_height(leg.get_bbox_to_anchor().height - pad)

This is heavily reliant on the answers here and here.

Answered By: Matt Pitkin
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.