How to Annotate Matplotlib Scatter Plots?

Scatter plots effectively visualize relationships between two continuous variables, revealing patterns, trends, and outliers. Adding annotations to specific points makes these visualizations more informative and easier to interpret. This article demonstrates how to annotate Matplotlib scatter plots using the annotate() method.

Syntax

ax.annotate(text, xy, xytext=None, arrowprops=None, **kwargs)

Parameters

  • text ? Text to be displayed in the annotation.

  • xy ? (x,y) coordinates of the point to annotate.

  • xytext ? (x,y) coordinates of the text annotation. If None (default), xy is used as the text location.

  • arrowprops ? A dictionary of arrow properties. It specifies the style and color of the arrow connecting the text and the annotated point. Common properties include facecolor, edgecolor, arrowstyle, shrink, and width.

  • **kwargs ? Additional keyword arguments passed to the Text constructor.

Note: ax is the Axes object returned when creating a scatter plot in Matplotlib.

Basic Annotation Example

Let's create a simple scatter plot with annotations pointing to specific data points ?

import matplotlib.pyplot as plt
import numpy as np

# Create sample data points
x = np.random.rand(30)
y = np.random.rand(30)

# Create scatter plot
fig, ax = plt.subplots(figsize=(8, 6))
ax.scatter(x, y, alpha=0.6)

# Add annotations to specific points
ax.annotate('Outlier', xy=(0.9, 0.9), xytext=(0.7, 0.7),
            arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('Important point', xy=(0.5, 0.3), xytext=(0.3, 0.1),
            arrowprops=dict(facecolor='red', shrink=0.05))
ax.annotate('Cluster region', xy=(0.2, 0.5), xytext=(0.05, 0.7),
            arrowprops=dict(facecolor='green', shrink=0.05))

# Customize plot
plt.title('Annotated Scatter Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True, alpha=0.3)
plt.show()

Advanced Annotation Styling

You can customize arrow styles and text formatting for more professional-looking annotations ?

import matplotlib.pyplot as plt
import numpy as np

# Create data with some specific points
np.random.seed(42)
x = np.random.normal(5, 2, 50)
y = np.random.normal(3, 1.5, 50)

# Add some outliers
x = np.append(x, [10, 1, 8])
y = np.append(y, [7, 6, 1])

# Create scatter plot
fig, ax = plt.subplots(figsize=(10, 6))
scatter = ax.scatter(x, y, c='blue', alpha=0.6, s=50)

# Highlight outliers with different styling
outliers_x = [10, 1, 8]
outliers_y = [7, 6, 1]
ax.scatter(outliers_x, outliers_y, c='red', s=100, alpha=0.8)

# Add styled annotations
ax.annotate('High outlier', xy=(10, 7), xytext=(8.5, 6),
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0.2', 
                          color='red', lw=2),
            bbox=dict(boxstyle='round,pad=0.3', facecolor='yellow', alpha=0.7),
            fontsize=12, fontweight='bold')

ax.annotate('Low outlier', xy=(8, 1), xytext=(6, 2),
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=-0.3',
                          color='orange', lw=2),
            bbox=dict(boxstyle='round,pad=0.3', facecolor='lightblue', alpha=0.7),
            fontsize=10)

# Customize plot
plt.title('Advanced Scatter Plot Annotations', fontsize=14, fontweight='bold')
plt.xlabel('X values', fontsize=12)
plt.ylabel('Y values', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

Annotating Multiple Points

For datasets with many points to annotate, you can loop through coordinates and labels ?

import matplotlib.pyplot as plt
import numpy as np

# Create sample data
cities = ['New York', 'London', 'Tokyo', 'Sydney', 'Mumbai']
population = [8.4, 8.9, 13.9, 5.3, 20.4]  # in millions
gdp_per_capita = [65, 45, 40, 55, 2]  # in thousands

fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(population, gdp_per_capita, s=100, c='darkblue', alpha=0.7)

# Annotate each city
for i, city in enumerate(cities):
    ax.annotate(city, 
                xy=(population[i], gdp_per_capita[i]),
                xytext=(5, 5),  # offset from point
                textcoords='offset points',
                fontsize=10,
                bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8))

plt.title('Population vs GDP per Capita by City', fontsize=14, fontweight='bold')
plt.xlabel('Population (millions)', fontsize=12)
plt.ylabel('GDP per Capita (thousands USD)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

Common Arrow Styles

Arrow Style Code Description
'->' arrowstyle='->' Simple arrow
'-|>' arrowstyle='-|>' Arrow with tail
'<->' arrowstyle='<->' Double-headed arrow
'fancy' arrowstyle='fancy' Fancy arrow style

Conclusion

Annotations transform scatter plots from simple data visualizations into informative, easy-to-interpret graphics. Use ax.annotate() with customized arrow styles and text formatting to highlight important data points, outliers, or patterns. Proper annotations make your scatter plots both visually appealing and analytically valuable.

Updated on: 2026-03-27T00:43:08+05:30

4K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements