5 Best Ways to Show Only Certain Items in Legend with Python Matplotlib

Rate this post

πŸ’‘ Problem Formulation: When visualizing data with Python’s Matplotlib library, it’s often desirable to customize the plot’s legend to display only a subset of the items. For instance, a plot with multiple lines for various data points might only require a few key lines to be annotated in the legend. This article demonstrates how to achieve a distilled and meaningful legend by showcasing only select items.

Method 1: Using Label as None

Matplotlib will not include a plot element in the legend if its label is set to None. This method involves explicitly setting the label parameter to None for those elements that should be omitted from the legend, thus creating a legend only for items with a specified label.

Here’s an example:

import matplotlib.pyplot as plt

# Plot multiple lines
plt.plot([1, 2, 3], label='Show in legend')
plt.plot([3, 2, 1], label=None)  # This line won’t show up in legend

plt.legend()
plt.show()

The output is a plot with two lines, but the legend will only display the first line.

In this snippet, two lines are plotted, but by setting the label parameter of the second one to None, we exclude it from appearing in the legend. This is a simple and effective way to filter legend entries when plotting your data.

Method 2: Handle/Label Lists

When calling the legend() function, you can pass custom handler and label lists. This allows for complete control over which items appear in the legend and their order. Only the specified handles (plot elements) and their corresponding labels will be shown in the legend.

Here’s an example:

import matplotlib.pyplot as plt

line1, = plt.plot([1, 2, 3], label='Line 1')
line2, = plt.plot([3, 2, 1], label='Line 2')

# Create a legend only for the first line
plt.legend(handles=[line1], labels=['Important Data Line'])

plt.show()

The output is a plot with a legend that only includes “Important Data Line”.

Here, we plot two lines and create a legend() that only includes the first line by providing a single-element list to the handles and labels parameters. This provides flexibility to customize legend entries and their respective labels.

Method 3: Using the Legend’s get_legend_handles_labels

Matplotlib’s get_legend_handles_labels() function retrieves the current handles and labels. Then, a new legend can be created with a subset of these handles and labels. This method is especially useful for dynamically updating the legend after the initial plot has been created.

Here’s an example:

import matplotlib.pyplot as plt

plt.plot([1, 2, 3], label='Line 1')
plt.plot([3, 2, 1], label='Line 2')

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

# Display a legend with only the first item
plt.legend(handles=handles[:1], labels=labels[:1])

plt.show()

The output is a plot with a legend that shows only “Line 1”.

In this code, get_legend_handles_labels() extracts the list of legends and labels from the current axis (gca()). By slicing these lists, we selectively include only the desired items in the legend displayed on the plot.

Method 4: Legend Artists

For complex plots that include non-standard plot elements, such as custom patches, it is possible to create legend artists. These custom legend entries can precisely specify which plot elements to include in the legend, ignoring others.

Here’s an example:

import matplotlib.pyplot as plt
from matplotlib.patches import Patch

plt.plot([1, 2, 3], label='Line 1')
plt.bar([1, 2, 3], [3, 2, 1], label='Bars')

legend_artist = Patch(color='blue', label='Only this legend')

plt.legend(handles=[legend_artist])

plt.show()

The output is a plot with a custom legend that says “Only this legend”.

Here, a Patch object is created to serve as a custom legend artist, overriding other plot elements. When calling plt.legend(), only the specified Patch is included in the legend, providing precise control over the legend content.

Bonus One-Liner Method 5: Comprehension and zip

This method combines Python’s list comprehension and the zip() function to filter the legend entries based on a condition. It’s concise and pythonic, ideal for cases where you need to dynamically decide which items will make it to the legend based on runtime data.

Here’s an example:

import matplotlib.pyplot as plt

lines = [plt.plot([1, 2, 3])[0] for _ in range(3)]  # Multiple lines
labels = ['First', 'Second', 'Third']

plt.legend([h for h, l in zip(lines, labels) if l != 'Second'], 
           [l for l in labels if l != 'Second'])

plt.show()

The output is a plot with a legend that includes “First” and “Third” lines, excluding “Second”.

This code uses a list comprehension to filter both the handles (`lines`) and the `labels` based on a condition. By using `zip()`, we pair each handle with its label and exclude the ones that don’t meet the criterion. The resulting lists are passed to `plt.legend()`.

Summary/Discussion

  • Method 1: Using Label as None. Strengths: Straightforward and clean when plotting. Weaknesses: Requires upfront decision during plot creation.
  • Method 2: Handle/Label Lists. Strengths: Provides full control over legend items and their order. Weaknesses: More boilerplate code and manual setup required.
  • Method 3: Using the Legend’s get_legend_handles_labels. Strengths: Great for dynamic plots where the legend changes over time. Weaknesses: Requires initial legends to be created.
  • Method 4: Legend Artists. Strengths: Maximum customization for complex plots. Weaknesses: Can be overkill for simple plots and requires understanding of artist objects.
  • Method 5: Comprehension and zip. Strengths: One-liner, pythonic, and flexible based on runtime conditions. Weaknesses: Assumes familiarity with list comprehensions and the zip function.