Matplotlib: Отсутствие меток в легенде и способы их добавления

Введение

Проблема отсутствия меток в легенде Matplotlib

При работе с библиотекой Matplotlib часто возникает ситуация, когда легенда (legend) на графике не отображается, либо отображается пустой. Это проявляется в виде предупреждения «No handles with labels found to put in legend.», которое указывает на то, что Matplotlib не смог найти элементы графика с назначенными метками, которые можно было бы отобразить в легенде.

Цель статьи: решение проблемы ‘No handles with labels found to put in legend.’

Целью данной статьи является разбор основных причин возникновения этой проблемы и предоставление конкретных способов ее решения. Мы рассмотрим различные сценарии, при которых легенда может не отображаться, и предоставим примеры кода, демонстрирующие правильное использование меток (labels) и функции plt.legend().

Причины отсутствия меток в легенде

Не указаны метки (labels) при построении графиков

Самая распространенная причина — отсутствие аргумента label при вызове функций построения графиков, таких как plt.plot(), plt.scatter() и т.д. Matplotlib использует значения label для формирования легенды.

Неправильное использование legend()

Вызов plt.legend() без предварительного создания графиков или до того, как графикам будут присвоены метки, приведет к пустой легенде.

Отсутствие данных для построения графика

Если в функцию построения графика переданы пустые данные, график не будет создан, и, следовательно, нечего будет отображать в легенде.

Использование объектов, не поддерживающих метки (например, plt.plot без возвращаемого значения)

В некоторых случаях, особенно при работе с более сложным кодом, можно упустить возвращаемое значение функции plt.plot() или аналогичной, и, следовательно, Matplotlib не сможет связать метку с конкретным графическим элементом.

Способы добавления меток в легенду

Указание меток при построении графиков (label=’…’)

Простейший и наиболее распространенный способ — указывать аргумент label непосредственно при построении графика. Это позволяет Matplotlib автоматически добавлять соответствующие элементы в легенду.

import matplotlib.pyplot as plt
from typing import List

def plot_ad_campaign(impressions: List[int], clicks: List[int], campaign_name: str) -> None:
    """Plots the impressions and clicks of an advertising campaign."""
    plt.plot(impressions, clicks, label=campaign_name)
    plt.xlabel("Impressions")
    plt.ylabel("Clicks")
    plt.title("Ad Campaign Performance")
    plt.legend()
    plt.show()

# Example usage
impressions = [1000, 2000, 3000, 4000, 5000]
clicks = [10, 25, 40, 55, 70]
plot_ad_campaign(impressions, clicks, "Summer Sale Campaign")

Использование plt.legend() с явным указанием дескрипторов и меток

Если метки не были указаны при построении графика, можно передать дескрипторы (handles) и метки непосредственно в функцию plt.legend().

import matplotlib.pyplot as plt
from typing import List, Tuple

def plot_multiple_metrics(data: List[Tuple[List[float], str]]) -> None:
    """Plots multiple metrics on the same graph.

    Args:
        data: A list of tuples, where each tuple contains a list of data points
              and a label for the data.
    """
    handles = []
    for values, label in data:
        line, = plt.plot(values, label=label) # The comma is important
        handles.append(line)

    plt.xlabel("Time")
    plt.ylabel("Value")
    plt.title("Multiple Metrics")

    plt.legend(handles=handles, labels=[label for _, label in data])
    plt.show()

# Example usage
data = [
    ([1, 2, 3, 4, 5], "Metric A"),
    ([2, 4, 6, 8, 10], "Metric B"),
    ([1.5, 3, 4.5, 6, 7.5], "Metric C"),
]
plot_multiple_metrics(data)

Добавление пользовательских дескрипторов (handles) в легенду

Этот способ полезен, когда необходимо добавить в легенду элементы, не представленные на графике напрямую (например, условные обозначения для областей).

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

def create_custom_legend() -> None:
    """Creates a plot with a custom legend."""

    # Create dummy data
    plt.plot([1, 2, 3], [4, 5, 6], label="Data Series")

    # Create custom legend handles
    red_patch = mpatches.Patch(color='red', label='The Red Data')
    blue_patch = mpatches.Patch(color='blue', label='The Blue Data')

    # Add the default and custom handles to the legend
    plt.legend(handles=[red_patch, blue_patch])
    plt.show()

create_custom_legend()

Примеры кода с исправленными метками

Примеры кода, демонстрирующие правильное добавление меток для различных типов графиков.

import matplotlib.pyplot as plt

# Corrected Example 1: Line Plot
x = [1, 2, 3]
y = [4, 5, 6]
plt.plot(x, y, label='Line Data')  # Added label
plt.legend()
plt.show()

# Corrected Example 2: Scatter Plot
x = [1, 2, 3]
y = [4, 5, 6]
plt.scatter(x, y, label='Scatter Data')  # Added label
plt.legend()
plt.show()

Примеры решения распространенных ошибок

Решение ошибки ‘No handles with labels found to put in legend.’

Убедитесь, что каждый графический элемент, который должен быть отображен в легенде, имеет атрибут label. Проверьте, что plt.legend() вызывается после построения всех графиков.

Работа с несколькими графиками на одном рисунке

При работе с несколькими графиками на одном рисунке, важно убедиться, что для каждого графика указана своя уникальная метка.

import matplotlib.pyplot as plt

x = [1, 2, 3]
y1 = [4, 5, 6]
y2 = [7, 8, 9]

plt.plot(x, y1, label='Series 1')
plt.plot(x, y2, label='Series 2')
plt.legend()
plt.show()

Использование legend для scatter plots

Для scatter plots метка также должна быть указана при вызове plt.scatter().

import matplotlib.pyplot as plt

x = [1, 2, 3]
y = [4, 5, 6]
plt.scatter(x, y, label='Data Points')
plt.legend()
plt.show()

Легенда для графиков, созданных в цикле

При создании графиков в цикле, важно, чтобы метка присваивалась внутри цикла для каждого созданного графика.

import matplotlib.pyplot as plt

data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
labels = ['Series A', 'Series B', 'Series C']

for i, series in enumerate(data):
    plt.plot(series, label=labels[i])

plt.legend()
plt.show()

Продвинутые техники работы с легендой

Настройка внешнего вида легенды (размер, шрифт, расположение)

plt.legend() принимает множество аргументов для настройки внешнего вида легенды, таких как fontsize, loc, frameon и другие. Например, plt.legend(fontsize='large', loc='upper right').

Размещение легенды за пределами области графика

Используйте bbox_to_anchor для размещения легенды за пределами осей. Например, plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.).

Создание нескольких легенд

Можно создать несколько легенд, если это необходимо для отображения информации о разных группах элементов графика. Это достигается путем ручного создания объектов Legend и их добавления на график.

Заключение

Основные выводы и рекомендации

Для корректного отображения легенды в Matplotlib необходимо убедиться, что каждому графическому элементу присвоена метка (label) при создании. Функция plt.legend() должна вызываться после построения всех графиков. Не забывайте, что можно настраивать внешний вид легенды и ее расположение для достижения наилучшего визуального представления.

Дополнительные ресурсы для изучения Matplotlib


Добавить комментарий