Adding a matplotlib legend

Learn adding a matplotlib legend with practical examples, diagrams, and best practices. Covers python, matplotlib, legend development techniques with visual explanations.

Mastering Matplotlib Legends: A Comprehensive Guide

Hero image for Adding a matplotlib legend

Learn how to add, customize, and position legends in Matplotlib plots to enhance data visualization clarity and interpretability.

Legends are crucial components of data visualizations, providing a key to understanding the different elements plotted on a graph. In Matplotlib, adding a legend is straightforward, but customizing it to fit your specific needs can sometimes be challenging. This article will guide you through the process of creating basic legends, customizing their appearance, and strategically positioning them for optimal readability in your Matplotlib plots.

Basic Legend Creation

The simplest way to add a legend in Matplotlib is to provide a label argument to each plot element (e.g., plt.plot(), plt.scatter()) and then call plt.legend(). Matplotlib automatically collects these labels and displays them in a legend box. Ensure each element you want in the legend has a unique label.

import matplotlib.pyplot as plt
import numpy as np

# Sample data
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# Plotting with labels
plt.plot(x, y1, label='Sine Wave')
plt.plot(x, y2, label='Cosine Wave')

# Add a legend
plt.legend()

# Add titles and labels for clarity
plt.title('Simple Sine and Cosine Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')

plt.grid(True)
plt.show()

Basic Matplotlib plot with a legend generated from plot labels.

Customizing Legend Appearance and Position

Matplotlib offers extensive options to customize the legend's appearance and position. You can control its location, font size, background, frame, and the number of columns. The loc argument is particularly useful for positioning, accepting string values like 'upper right', 'lower left', or integer codes (e.g., 1 for 'upper right'). For more precise control, you can use bbox_to_anchor.

flowchart TD
    A["Start: Define Plot Elements"] --> B{"Are labels provided?"}
    B -- Yes --> C["Call `plt.legend()`"]
    C --> D{"Default Legend Position (best)"}
    D -- No --> E["Customize `loc` argument"]
    E --> F["Further Customization (e.g., `fontsize`, `frameon`, `ncol`)"]
    F --> G["Need precise position? Use `bbox_to_anchor`"]
    G --> H["End: Display Plot with Custom Legend"]
    B -- No --> I["Legend will be empty or not appear"]
    I --> H

Decision flow for adding and customizing Matplotlib legends.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.sin(x) * np.cos(x)

plt.figure(figsize=(10, 6))
plt.plot(x, y1, label='Sine Wave', color='blue', linestyle='-')
plt.plot(x, y2, label='Cosine Wave', color='red', linestyle='--')
plt.plot(x, y3, label='Product Wave', color='green', linestyle=':')

# Customizing the legend
plt.legend(
    loc='upper left',          # Position the legend
    fontsize='medium',         # Font size
    frameon=True,              # Show frame around legend
    shadow=True,               # Add shadow
    facecolor='lightgray',     # Background color
    edgecolor='black',         # Frame color
    ncol=2,                    # Number of columns
    title='Wave Types',        # Legend title
    borderpad=1,               # Padding inside legend box
    labelspacing=0.5           # Vertical space between legend entries
)

plt.title('Customized Legend Example')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True)
plt.show()

Example demonstrating various legend customization options.

Handling Multiple Legends and Advanced Scenarios

Sometimes, you might need to display multiple legends on a single plot, or create a legend for elements that aren't directly returned by plt.plot() (e.g., plt.fill_between). This can be achieved by manually creating legend handles and labels. You can also create a legend from a subset of plotted items or combine multiple legends.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

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

# Plotting with labels
line1, = ax.plot(x, y1, label='Series A', color='purple', linewidth=2)
line2, = ax.plot(x, y2, label='Series B', color='orange', linestyle='--')

# Manually create a legend for specific items
legend1 = ax.legend(handles=[line1], loc='upper left', title='Primary Data')

# Add the second legend for another item
# It's important to add the first legend back to the axes after creating the second
ax.add_artist(legend1)
legend2 = ax.legend(handles=[line2], loc='lower left', title='Secondary Data')

ax.set_title('Plot with Multiple Legends')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.grid(True)
plt.show()

Creating a plot with two separate legends using ax.add_artist().

1. Define Plot Elements with Labels

For each line, bar, or scatter plot you want in the legend, include the label='Your Label' argument in its plotting function (e.g., plt.plot(x, y, label='Data Series')).

2. Call plt.legend()

After all plot elements are defined, call plt.legend() to display the legend. Matplotlib will automatically collect all labels and create the legend box.

3. Customize Position and Appearance (Optional)

Pass arguments to plt.legend() such as loc='upper right', fontsize='small', ncol=2, frameon=False, or bbox_to_anchor=(x, y) for fine-tuned control over its look and placement.

4. Handle Multiple Legends (Advanced)

If you need more than one legend, create each legend separately, storing them in variables (e.g., legend1 = ax.legend(...)). After creating a subsequent legend, use ax.add_artist(legend1) to re-add previous legends to the plot.