Создание общей легенды для всех подграфиков в Matplotlib: подробное руководство

Зачем нужна общая легенда?

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

Краткий обзор Matplotlib и подграфиков

Matplotlib – это мощная библиотека для визуализации данных на Python. Она предоставляет широкий спектр инструментов для создания графиков, диаграмм и других визуальных представлений данных. Подграфики (subplots) позволяют организовать несколько графиков в одной фигуре, что полезно для сравнения различных аспектов данных.

Цель руководства

В этом руководстве мы подробно рассмотрим различные методы создания общей легенды для подграфиков в Matplotlib, начиная с базовых и заканчивая более продвинутыми техниками. Мы также обсудим настройку внешнего вида легенды и решение распространенных проблем.

Основы создания подграфиков в Matplotlib

Использование plt.subplots() для создания нескольких графиков

Функция plt.subplots() – основной инструмент для создания подграфиков. Она возвращает кортеж, содержащий объект фигуры (figure) и массив осей (axes), представляющих каждый подграфик.

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

Подграфики обычно размещаются в сетке. Параметры nrows и ncols в plt.subplots() определяют количество строк и столбцов в сетке. Например, plt.subplots(nrows=2, ncols=2) создаст сетку 2×2.

Пример: несколько графиков с разными данными

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


def generate_sample_data(n: int) -> Tuple[List[float], List[float]]:
    """Generates sample data for plotting."""
    x = np.linspace(0, 10, n)
    y = np.sin(x) + np.random.normal(0, 0.1, n)
    return x.tolist(), y.tolist()


def create_subplots(nrows: int, ncols: int) -> Tuple[plt.Figure, np.ndarray]:
    """Creates a figure with subplots."""
    fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(10, 8))
    return fig, axes


def plot_data_on_subplots(axes: np.ndarray, data: List[Tuple[List[float], List[float]]], labels: List[str]) -> None:
    """Plots data on the given subplots."""
    for i, ax in enumerate(axes.flatten()):
        x, y = data[i]
        ax.plot(x, y, label=labels[i])
        ax.set_title(f'Subplot {i+1}')
        ax.set_xlabel('X-axis')
        ax.set_ylabel('Y-axis')


if __name__ == '__main__':
    # Generate data for 4 subplots
    data = [generate_sample_data(50) for _ in range(4)]
    labels = ['Series 1', 'Series 2', 'Series 3', 'Series 4']

    # Create a 2x2 grid of subplots
    fig, axes = create_subplots(nrows=2, ncols=2)

    # Plot data on each subplot
    plot_data_on_subplots(axes, data, labels)

    # Add a title to the entire figure
    fig.suptitle('Example Subplots', fontsize=16)

    # Adjust layout to prevent overlapping
    plt.tight_layout(rect=[0, 0.03, 1, 0.95])  # Adjust rect to make space for the suptitle

    plt.show()

Методы создания общей легенды

Существует несколько способов добавить общую легенду к подграфикам:

  1. Использование fig.legend() после создания всех подграфиков. Это самый простой и распространенный метод.
  2. Извлечение дескрипторов и меток из подграфиков. Более гибкий метод, полезный при сложной структуре графиков.
  3. Использование constrained_layout для автоматического размещения. Подходит для автоматической компоновки графиков и легенды.

Подробное руководство: fig.legend()

Создание подграфиков

Сначала необходимо создать фигуру и подграфики с помощью plt.subplots().

Построение графиков на подграфиках и присвоение меток

При построении графиков на каждом подграфике используйте параметр label для присвоения меток каждой серии данных. Эти метки будут использоваться в легенде.

Вызов fig.legend() для отображения общей легенды

После построения всех графиков вызовите функцию fig.legend() для отображения общей легенды. Передайте в нее дескрипторы и метки, полученные из подграфиков.

Настройка положения легенды

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

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


def generate_data() -> Tuple[List[float], List[float], List[float]]:
    """Generates sample data for the plots."""
    x = np.linspace(0, 10, 100)
    y1 = np.sin(x)
    y2 = np.cos(x)
    return x.tolist(), y1.tolist(), y2.tolist()


def create_and_plot_subplots(x: List[float], y1: List[float], y2: List[float]) -> plt.Figure:
    """Creates subplots and plots the data."""
    fig, axs = plt.subplots(2, 1, figsize=(8, 6))

    # Plot on the first subplot
    axs[0].plot(x, y1, label='Sine Wave', color='blue')
    axs[0].set_title('Sine Wave Plot')
    axs[0].set_xlabel('X-axis')
    axs[0].set_ylabel('Y-axis')

    # Plot on the second subplot
    axs[1].plot(x, y2, label='Cosine Wave', color='red')
    axs[1].set_title('Cosine Wave Plot')
    axs[1].set_xlabel('X-axis')
    axs[1].set_ylabel('Y-axis')

    return fig


if __name__ == '__main__':
    # Generate the data
    x, y1, y2 = generate_data()

    # Create and plot the subplots
    fig = create_and_plot_subplots(x, y1, y2)

    # Add a common legend to the entire figure
    fig.legend(loc='upper center', bbox_to_anchor=(0.5, 0.05), ncol=2)

    # Adjust layout to prevent labels from overlapping
    plt.tight_layout(rect=[0, 0.07, 1, 0.95])  # Adjust rect to make space for the legend

    # Show the plot
    plt.show()

Подробное руководство: Извлечение дескрипторов и меток

Получение дескрипторов и меток из каждого подграфика

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

Объединение дескрипторов и меток в один список

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

Создание легенды с использованием объединенных дескрипторов и меток

Используйте функцию plt.legend() и передайте ей объединенные списки дескрипторов и меток.

Преимущества и недостатки этого метода

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

Использование constrained_layout

Включение constrained_layout

constrained_layout – это функция автоматической компоновки, которая позволяет автоматически размещать подграфики и другие элементы фигуры, включая легенду. Чтобы ее включить, установите constrained_layout=True при создании фигуры: fig, ax = plt.subplots(..., constrained_layout=True).

Преимущества автоматической компоновки

Основное преимущество constrained_layout – автоматическое предотвращение перекрытия элементов графика. Она также позволяет легко настраивать отступы и интервалы.

Ограничения и возможные проблемы

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

Настройка внешнего вида общей легенды

Изменение шрифта, размера и цвета текста легенды

Внешний вид текста легенды можно настроить с помощью параметров fontsize, fontweight и color. Например: fig.legend(..., fontsize='large', fontweight='bold', labelcolor='green').

Изменение рамки и фона легенды

Рамку и фон легенды можно настроить с помощью параметров edgecolor, facecolor и framealpha. Например: fig.legend(..., edgecolor='black', facecolor='lightgray', framealpha=0.5).

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

Размещение легенды за пределами подграфиков можно настроить с помощью параметра bbox_to_anchor. Это позволяет разместить легенду в любом месте фигуры, даже за пределами области графиков.

Использование различных стилей легенды

Matplotlib предоставляет различные стили легенды, которые можно настроить с помощью параметров shadow, fancybox и borderpad. Например: fig.legend(..., shadow=True, fancybox=True, borderpad=1).

Решение распространенных проблем

Перекрытие легенды и графиков

Эта проблема часто возникает при использовании fig.legend() с настройками по умолчанию. Решение: Используйте bbox_to_anchor для точного размещения легенды за пределами области графиков, либо примените plt.tight_layout() или constrained_layout=True для автоматической корректировки.

Неправильное отображение меток

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

Некорректное положение легенды

Используйте параметры loc и bbox_to_anchor для точной настройки положения легенды. Экспериментируйте с разными значениями, чтобы найти оптимальное расположение.

Примеры продвинутого использования

Общая легенда для подграфиков разных типов

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

Интерактивная легенда (с использованием plotly или bokeh) — краткий обзор

Для создания интерактивных легенд можно использовать библиотеки plotly или bokeh. Они позволяют добавлять интерактивные элементы управления, такие как фильтры и переключатели, к легенде. Это значительно улучшает взаимодействие с данными.
Например, в plotly можно использовать go.Figure и fig.update_layout(legend=...) для настройки интерактивной легенды. В bokeh можно использовать Legend и LegendItem для создания кастомизированных легенд с интерактивными возможностями.

Заключение

Краткое повторение основных методов

Мы рассмотрели три основных метода создания общей легенды для подграфиков в Matplotlib: fig.legend(), извлечение дескрипторов и меток, и использование constrained_layout. Каждый метод имеет свои преимущества и недостатки, и выбор зависит от конкретной задачи и сложности графиков.

Дополнительные ресурсы и ссылки


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