How to add legend to imshow() in Matplotlib?

Adding a legend to imshow() in Matplotlib requires creating proxy artists since imshow() doesn't directly support legends. You can use plot() with invisible points or patches.Patch objects to create legend entries.

Method 1: Using Invisible Plot Points

Create invisible plot points with different colors to represent data ranges ?

import numpy as np
from matplotlib import pyplot as plt, cm

plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True

# Create sample data
data = np.random.rand(3, 3)
cmap = cm.YlOrBr

# Get unique data values for legend
unique_data = np.unique(data)

# Create invisible plot points for legend
for i, entry in enumerate(unique_data):
    # Calculate color based on data value
    normalized_value = (entry - min(unique_data)) / (max(unique_data) - min(unique_data))
    color = cmap(normalized_value)
    
    # Plot invisible point (0,0) with specific color and label
    plt.plot(0, 0, "-", color=color, label=f"Value {i+1}: {entry:.3f}")

# Display the image
plt.imshow(data, cmap=cmap)

# Add legend outside the plot area
plt.legend(loc="upper right", bbox_to_anchor=(1.4, 1.0))
plt.show()

Method 2: Using Patches for Better Control

Use matplotlib.patches to create colored rectangles for the legend ?

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib import cm

# Create sample data
data = np.array([[0.1, 0.4, 0.7],
                 [0.3, 0.6, 0.9],
                 [0.2, 0.5, 0.8]])

cmap = cm.viridis

# Create legend patches
patches = []
labels = ['Low (0.0-0.3)', 'Medium (0.3-0.7)', 'High (0.7-1.0)']
colors = [cmap(0.1), cmap(0.5), cmap(0.9)]

for color, label in zip(colors, labels):
    patches.append(mpatches.Patch(color=color, label=label))

# Display image with legend
plt.figure(figsize=(8, 4))
plt.imshow(data, cmap=cmap)
plt.colorbar(label='Data Values')
plt.legend(handles=patches, loc='upper left', bbox_to_anchor=(1.1, 1))
plt.title('Image with Custom Legend')
plt.tight_layout()
plt.show()

Method 3: Combining with Colorbar

Use both a colorbar and custom legend for comprehensive data representation ?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

# Create structured data
np.random.seed(42)
data = np.random.rand(4, 4)

# Define regions
regions = np.where(data < 0.3, 1,
          np.where(data < 0.7, 2, 3))

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

# Original data with colorbar
im1 = ax1.imshow(data, cmap='coolwarm')
ax1.set_title('Original Data')
plt.colorbar(im1, ax=ax1, label='Values')

# Regions with legend
im2 = ax2.imshow(regions, cmap='Set3', vmin=1, vmax=3)
ax2.set_title('Data Regions')

# Create custom legend for regions
legend_elements = [plt.Line2D([0], [0], marker='s', color='w', 
                             markerfacecolor=cm.Set3(0.1), markersize=10, label='Low (< 0.3)'),
                  plt.Line2D([0], [0], marker='s', color='w', 
                             markerfacecolor=cm.Set3(0.5), markersize=10, label='Medium (0.3-0.7)'),
                  plt.Line2D([0], [0], marker='s', color='w', 
                             markerfacecolor=cm.Set3(0.9), markersize=10, label='High (> 0.7)')]

ax2.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(1.05, 1))
plt.tight_layout()
plt.show()

Comparison

Method Best For Advantages Disadvantages
Invisible Plot Points Simple legends Quick to implement Limited customization
Patches Custom categories Full control over appearance More code required
With Colorbar Continuous + discrete data Shows both scales Takes more space

Conclusion

Use invisible plot points for quick legends, patches for custom categorical data, or combine with colorbars for comprehensive visualization. The bbox_to_anchor parameter helps position legends outside the plot area to avoid overlapping with the image.

Updated on: 2026-03-25T23:19:20+05:30

5K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements