Зачем нужна общая легенда?
При работе с большим количеством графиков, объединенных в подграфики (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()
Методы создания общей легенды
Существует несколько способов добавить общую легенду к подграфикам:
- Использование
fig.legend()
после создания всех подграфиков. Это самый простой и распространенный метод. - Извлечение дескрипторов и меток из подграфиков. Более гибкий метод, полезный при сложной структуре графиков.
- Использование
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
. Каждый метод имеет свои преимущества и недостатки, и выбор зависит от конкретной задачи и сложности графиков.