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")
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()
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.
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")
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()
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.