Annotations draw attention to a specific value without separating the explanation from the plot. A well-placed label can identify a peak, threshold, or unusual point while the surrounding series remains visible.
The Axes.annotate() method treats the target and the label as separate positions. xy identifies the point being described, while xytext controls where the text appears and arrowprops connects the two positions.
Selecting the highest value from the data keeps the callout attached to the peak when the values change. Setting textcoords=“offset points” keeps the label a fixed physical distance from the marker even when the data range changes.
Related: How to create a line chart in Matplotlib
Related: How to set axis labels in Matplotlib
Related: How to save a Matplotlib figure
from pathlib import Path import matplotlib import matplotlib.pyplot as plt months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] revenue = [62, 68, 71, 86, 91, 88] fig, ax = plt.subplots(figsize=(6, 3.5), layout="constrained") ax.plot(months, revenue, marker="o", linewidth=2.5, color="#2563eb")
peak_index = revenue.index(max(revenue)) peak_month = months[peak_index] peak_value = revenue[peak_index]
list.index() returns the first matching position when the maximum value occurs more than once.
annotation = ax.annotate( f"Peak month\n{peak_value}k", xy=(peak_month, peak_value), xytext=(32, 26), textcoords="offset points", arrowprops={"arrowstyle": "->", "color": "#1f2937", "linewidth": 1.3}, bbox={"boxstyle": "round,pad=0.3", "fc": "#fef3c7", "ec": "#92400e"}, ha="left", va="bottom", )
xy uses the plot's data coordinates. The xytext pair moves the text 32 points right and 26 points up from that anchor.
ax.set_ylabel("Revenue (USD thousands)") ax.set_title("Quarterly campaign revenue") ax.grid(True, axis="y", color="#e5e7eb") ax.set_ylim(55, 100)
output = Path("annotation-add.png") fig.savefig(output, dpi=160) plt.close(fig)
print(f"matplotlib: {matplotlib.__version__}") print(f"annotation: {annotation.get_text().replace(chr(10), ' / ')}") print(f"anchor: {annotation.xy}") print(f"offset points: {annotation.get_position()}") print(f"saved: {output} ({output.stat().st_size} bytes)")
$ python3 annotation-add.py
matplotlib: 3.10.7+dfsg1
annotation: Peak month / 91k
anchor: ('May', 91)
offset points: (32, 26)
saved: annotation-add.png (49585 bytes)
The byte count can vary with the Matplotlib release, fonts, backend, and image metadata.
