How to add titles to the legend rows in Matplotlib?

In Matplotlib, adding titles to legend rows helps organize multiple data series into logical groups. This technique uses phantom plot handles to create section headers within the legend.

Basic Approach

The key steps are creating phantom handles (invisible plot elements) and inserting them as section dividers in your legend ?

import matplotlib.pyplot as plt
import numpy as np

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

# Create sample data
y = np.exp(-np.arange(5))

markers = ["s", "o", "*"]
labels = ["Series A", "Series B"]

fig, ax = plt.subplots()

# Plot multiple lines with different markers and labels
for i in range(6):
    ax.plot(y * i + i / 2., marker=markers[i // 2], label=labels[i % 2])

# Get existing handles and labels
h, l = ax.get_legend_handles_labels()

# Create phantom handles for titles (invisible plot elements)
ph = [plt.plot([], marker="", ls="")[0]] * 2

# Combine phantom handles with actual handles
handles = ph + h

# Create title labels and combine with data labels
title_labels = ["Group 1:", "Group 2:"] + l
plt.legend(handles, title_labels, ncol=4)

plt.show()

How It Works

The phantom handles are created using empty plots with no markers or line styles. These act as placeholders that display only text in the legend ?

import matplotlib.pyplot as plt
import numpy as np

# Create data
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.sin(x + np.pi/4)

fig, ax = plt.subplots(figsize=(8, 5))

# Plot different series
ax.plot(x, y1, 'r-', label='sin(x)')
ax.plot(x, y2, 'b-', label='cos(x)')
ax.plot(x, y3, 'g-', label='sin(x+?/4)')

# Get current handles and labels
handles, labels = ax.get_legend_handles_labels()

# Create phantom handle for section title
phantom = plt.plot([], marker="", ls="")[0]

# Insert title at the beginning
final_handles = [phantom] + handles
final_labels = ["Trigonometric Functions:"] + labels

plt.legend(final_handles, final_labels, loc='upper right')
plt.grid(True, alpha=0.3)
plt.show()

Multiple Section Titles

For complex plots with multiple groups, you can insert titles at different positions ?

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 5, 50)

fig, ax = plt.subplots(figsize=(9, 6))

# Plot linear functions
ax.plot(x, x, 'r-', label='y = x')
ax.plot(x, 2*x, 'r--', label='y = 2x')

# Plot quadratic functions  
ax.plot(x, x**2, 'b-', label='y = x²')
ax.plot(x, 0.5*x**2, 'b--', label='y = 0.5x²')

# Get all handles and labels
handles, labels = ax.get_legend_handles_labels()

# Create phantom handles for section titles
phantom1 = plt.plot([], marker="", ls="")[0]
phantom2 = plt.plot([], marker="", ls="")[0]

# Organize handles: Title1, Linear plots, Title2, Quadratic plots
organized_handles = [phantom1, handles[0], handles[1], phantom2, handles[2], handles[3]]
organized_labels = ["Linear Functions:", labels[0], labels[1], "Quadratic Functions:", labels[2], labels[3]]

plt.legend(organized_handles, organized_labels, loc='upper left')
plt.grid(True, alpha=0.3)
plt.show()

Key Points

  • plt.plot([], marker="", ls="")[0] creates an invisible plot handle

  • Phantom handles act as text-only legend entries

  • Use ncol parameter to control legend column layout

  • Insert phantom handles at desired positions in the handle list

Conclusion

Adding titles to legend rows using phantom handles helps organize complex plots with multiple data series. This technique creates clear section dividers within the legend for better readability.

Updated on: 2026-03-26T00:22:13+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements