While titles, axis labels, and legends provide essential context for your plots, sometimes you need to add specific text directly onto the visualization itself. This could be to label a particular data point, highlight a region of interest, explain an anomaly, or add other contextual information that doesn't fit neatly into standard plot elements. Matplotlib provides flexible tools for adding text and annotations precisely where you need them.
text()
The most straightforward way to add text to a Matplotlib plot is using the plt.text()
function (or the equivalent ax.text()
method if you are using the object-oriented approach with an Axes
object, often referred to as ax
). This function places text at specified coordinates within the plot's data space.
The basic syntax is:
plt.text(x, y, 'Your desired text string')
Here, x
and y
are the coordinates where the text will begin, based on the data scale of your axes.
Let's look at an example:
import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 2 * np.pi, 100)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Create the plot
plt.figure(figsize=(8, 5)) # Create a figure
plt.plot(x, y_sin, label='sin(x)', color='#1c7ed6') # Blue
plt.plot(x, y_cos, label='cos(x)', color='#fd7e14') # Orange
plt.title('Sine and Cosine Waves')
plt.xlabel('Angle (radians)')
plt.ylabel('Value')
plt.legend()
plt.grid(True, linestyle=':', alpha=0.6)
# Add text using plt.text()
plt.text(np.pi / 2, 1.05, 'Sine peak', ha='center', va='bottom', color='#1c7ed6')
plt.text(np.pi, -1.05, 'Cosine minimum', ha='center', va='top', color='#fd7e14')
plt.text(4, 0, 'Intersection point', ha='left', va='center', fontsize=9, color='#495057') # Gray
plt.ylim(-1.5, 1.5) # Adjust y-limits to make space for text
plt.show()
In this example:
plt.text()
three times to add labels near specific points.ha
(or horizontalalignment
): Controls horizontal alignment ('center', 'left', 'right').va
(or verticalalignment
): Controls vertical alignment ('center', 'top', 'bottom', 'baseline').color
: Sets the text color.fontsize
: Adjusts the size of the text.Using plt.text()
is great for general labels, but aligning text precisely relative to a specific data point, especially with a pointer, often requires annotations.
annotate()
When you want to draw attention to a specific point or feature on your plot and add descriptive text, plt.annotate()
(or ax.annotate()
for the object-oriented approach) is more suitable. It allows you to specify both the location of the point being annotated and the location of the text label, often connecting them with an arrow.
The core syntax involves:
plt.annotate('Annotation text',
xy=(x_point, y_point), # The point to annotate
xytext=(x_text, y_text), # Where the text should be
arrowprops=dict(...) # Properties for the arrow
)
'Annotation text'
is the string you want to display.xy
is a tuple (x, y)
representing the coordinates of the point you are annotating (the arrowhead points here). These are typically in data coordinates.xytext
is a tuple (x, y)
representing the coordinates where the text label should be placed. By default, these are also in data coordinates.arrowprops
is a dictionary defining the appearance of the arrow connecting xytext
to xy
. If you omit arrowprops
or set it to None
, no arrow will be drawn.Let's annotate the first peak of the sine wave from the previous example:
import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 2 * np.pi, 100)
y_sin = np.sin(x)
# Find the first peak (approximate)
peak_x = np.pi / 2
peak_y = np.sin(peak_x) # This is 1.0
# Create the plot
fig, ax = plt.subplots(figsize=(8, 5)) # Using object-oriented approach now
ax.plot(x, y_sin, color='#1c7ed6') # Blue
ax.set_title('Annotating the Sine Wave Peak')
ax.set_xlabel('Angle (radians)')
ax.set_ylabel('Value')
ax.grid(True, linestyle=':', alpha=0.6)
# Add annotation using ax.annotate()
ax.annotate('First Peak (x=π/2)',
xy=(peak_x, peak_y), # Point to annotate (data coords)
xytext=(peak_x + 1, peak_y + 0.3), # Text location (data coords)
arrowprops=dict(facecolor='#495057', # Arrow color (gray)
edgecolor='#495057',
shrink=0.05, # Gap between arrow and points
arrowstyle='->', # Arrow style
connectionstyle='arc3,rad=0.2' # Curved arrow
),
fontsize=10,
color='#495057' # Gray text
)
# Mark the point itself for clarity
ax.plot(peak_x, peak_y, 'o', color='#f03e3e') # Red marker at the peak
ax.set_ylim(-1.2, 1.5) # Ensure space for annotation
plt.show()
In this code:
Figure
and Axes
object using plt.subplots()
. This allows us to use ax.annotate()
.(peak_x, peak_y)
of the sine wave's first peak.xy
argument points the arrow directly at this peak.xytext
argument positions the text label slightly above and to the right of the peak.arrowprops
dictionary defines the arrow's appearance:
facecolor
and edgecolor
set the arrow color.shrink
creates a small gap between the arrow ends and the points they connect.arrowstyle
defines the type of arrowhead (e.g., '->', '-|>', '<|-|>', 'fancy').connectionstyle
controls the path of the arrow line (e.g., 'arc3,rad=0.2' creates a curved arrow; 'angle3' creates a bent arrow). Experimenting with these values is often necessary to get the desired look.ax.plot()
at the annotated point to make it visually distinct.While xy
and xytext
default to data coordinates, annotate
offers sophisticated control over coordinate systems using the xycoords
and textcoords
arguments (e.g., placing text relative to the figure or axes boundaries). However, for many common use cases, relying on data coordinates is sufficient and more intuitive.
text
and annotate
text()
when you need a simple text label placed at a specific data coordinate, without needing an explicit pointer.annotate()
when you want to specifically highlight a data point or feature and draw a visual connection (an arrow) between the feature and its description. annotate
provides more control over positioning the text relative to the point of interest.Adding text and annotations requires careful consideration. Ensure your additions clarify the plot rather than cluttering it. Use them purposefully to guide the viewer's attention to the most significant aspects of your data visualization.
© 2025 ApX Machine Learning