ax.text places a string in data coordinates. ax.annotate can add an arrow from the text to a point.
Goal
Label a peak and write a short note on the Axes.
text
x = np.linspace(0, 2 * np.pi, 80)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.text(0.2, 0.85, "rising", transform=ax.transAxes)
ax.set_title("ax.text in Axes fraction coords")
plt.show()transform=ax.transAxes uses 0–1 in the Axes (left–right, bottom–top), so the note stays put if you zoom.
annotate a peak
months = ["Jan", "Feb", "Mar", "Apr"]
nairobi = np.array([50, 40, 80, 150], dtype=float)
peak_i = int(np.argmax(nairobi))
fig, ax = plt.subplots()
ax.plot(months, nairobi, marker="o")
ax.annotate(
f"peak {nairobi[peak_i]:.0f} mm",
xy=(peak_i, nairobi[peak_i]),
xytext=(peak_i - 1.2, nairobi[peak_i] - 40),
arrowprops={"arrowstyle": "->", "color": "0.3"},
)
ax.set_ylabel("mm")
ax.set_title("Nairobi rainfall")
plt.show()xy is the point; xytext is where the words sit. With string x-ticks, using the index as xy[0] matches the default 0, 1, 2, … positions.
Tip
If the arrow misses the marker, print ax.get_xticks() — category plots often sit at 0, 1, 2, not at the string values.