Add a label to y-axis to show the value of y for a horizontal line in matplotlib

Question:

How can I add a string label to the horizontal red line showed in the following plot? I want to add something like “k=305” to the y-axis label next to the line. The blue dots are just some other data and the values do not matter. For recreation of this problem, you can plot any kind of data. My question is about the red line.

plt.plot((0,502),(305,305),'r-')
plt.title("ALS+REG")

plot

Asked By: HimanAB

||

Answers:

A horizontal line can be drawn using Axes.axhline(y).
Adding a label would be done by using Axes.text(). THe tricky bit is to decide upon the coordinates at which to place that text. Since the y coordinate should be the data coordinate at which the line is drawn, but the x coordinate of the label should be the independent of the data (e.g. allow for differen axis scales), we can use a blended transform, where the x transform is the transform of the axis ylabels, and the y transform is the data coordinate system.

import matplotlib.pyplot as plt
import matplotlib.transforms as transforms
import numpy as np; np.random.seed(42)

N = 120
x = np.random.rand(N)
y = np.abs(np.random.normal(size=N))*1000
mean= np.mean(y)

fig, ax=plt.subplots()
ax.plot(x,y, ls="", marker="o", markersize=2)
ax.axhline(y=mean, color="red")

trans = transforms.blended_transform_factory(
    ax.get_yticklabels()[0].get_transform(), ax.transData)
ax.text(0,mean, "{:.0f}".format(mean), color="red", transform=trans, 
        ha="right", va="center")

plt.show()

enter image description here

Instead of adding a label through text and having to position it yourself, you can add a new tick and an associated label to the list of existing yticks directly thanks to the method Axes.set_yticks. It avoids having to perform complicated operations to compute the coordinates of the label.

Here is an example reusing the code from ImportanceOfBeingErnest’s answer:

import matplotlib.pyplot as plt
import matplotlib.transforms as transforms
import numpy as np; np.random.seed(42)

N = 120
x = np.random.rand(N)
y = np.abs(np.random.normal(size=N)) * 1000
mean = np.mean(y)

fig, ax = plt.subplots()
ax.plot(x, y, ls="", marker="o")
ax.axhline(y=mean, color="red")

# Here: add a new tick with the required value
yticks = [*ax.get_yticks(), mean]
yticklabels = [*ax.get_yticklabels(), int(mean)]
ax.set_yticks(yticks, labels=yticklabels)

plt.show()

Compared to the accepted answer, this solution does not allow to give a different color to the new tick as far as I know. However, it is arguably much simpler, and also works when the y axis is displayed on the right side of the figure.

Picture showing a matplotlib graph with a horizontal line and the corresponding label added as a tick

Answered By: Morwenn
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.