Matplotlib: Как создать подграфики с разным количеством графиков в строке?

Что такое подграфики и зачем они нужны?

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

В контексте анализа данных и интернет-маркетинга, подграфики могут использоваться для:

  • Сравнения эффективности различных рекламных кампаний.
  • Визуализации изменения ключевых метрик (например, CTR, конверсия) во времени.
  • Отображения результатов A/B тестирования.
  • Представления данных о пользовательском поведении на сайте.

Основы создания подграфиков с помощью plt.subplot() и plt.subplots()

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

  • plt.subplot(): Позволяет создавать отдельные оси (axes) в рамках сетки. Требует указания индекса ячейки, в которой будет размещен график.
  • plt.subplots(): Создает окно (figure) и набор осей (axes) в виде NumPy массива. Более удобен для создания множества подграфиков.

Краткий обзор различных способов организации подграфиков

Существуют различные способы организации подграфиков, включая:

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

Создание подграфиков с разным количеством графиков в строке: Основные подходы

Использование plt.subplot() для точного контроля размещения

Функция plt.subplot() позволяет точно указать положение подграфика в сетке. Она принимает три аргумента: nrows, ncols и index. index определяет положение подграфика в сетке, начиная с 1.

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

def create_subplot_example() -> None:
    """Creates a subplot example using plt.subplot()."""
    plt.figure(figsize=(10, 6))

    # Первый график в первой строке (1 строка, 2 столбца, 1-я ячейка)
    plt.subplot(2, 1, 1)
    plt.plot([1, 2, 3], [4, 5, 6])
    plt.title('График 1')

    # Второй график во второй строке (1 строка, 2 столбца, 2-я ячейка)
    plt.subplot(2, 1, 2)
    plt.plot([1, 2, 3], [6, 5, 4])
    plt.title('График 2')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    create_subplot_example()

Применение plt.subplots() с аргументом gridspec_kw для настройки сетки

Функция plt.subplots() с аргументом gridspec_kw позволяет более гибко настраивать сетку подграфиков. gridspec_kw — это словарь, который передается в конструктор GridSpec.

import matplotlib.pyplot as plt
import numpy as np

def create_subplots_gridspec_example() -> None:
    """Creates a subplot example using plt.subplots() and gridspec_kw."""
    fig, axes = plt.subplots(2, 2, gridspec_kw={'width_ratios': [3, 1], 'height_ratios': [1, 3]})

    # axes - это двумерный numpy массив
    axes[0, 0].plot([1, 2, 3], [4, 5, 6])
    axes[0, 0].set_title('График 1')

    axes[1, 0].plot([1, 2, 3], [6, 5, 4])
    axes[1, 0].set_title('График 2')

    axes[0, 1].plot([1, 2, 3], [5, 4, 6])
    axes[0, 1].set_title('График 3')

    axes[1, 1].plot([1, 2, 3], [4, 6, 5])
    axes[1, 1].set_title('График 4')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    create_subplots_gridspec_example()

Использование GridSpec для более сложной компоновки

GridSpec — это класс, который позволяет создавать сложные макеты подграфиков, объединяя ячейки сетки. Он обеспечивает наибольшую гибкость в управлении размещением графиков.

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

def create_gridspec_example() -> None:
    """Creates a subplot example using GridSpec."""
    fig = plt.figure(figsize=(10, 6))
    gs = gridspec.GridSpec(2, 2)

    ax1 = fig.add_subplot(gs[0, :])  # Первый график занимает всю первую строку
    ax1.plot([1, 2, 3], [4, 5, 6])
    ax1.set_title('График 1')

    ax2 = fig.add_subplot(gs[1, 0])  # Второй график занимает первую ячейку второй строки
    ax2.plot([1, 2, 3], [6, 5, 4])
    ax2.set_title('График 2')

    ax3 = fig.add_subplot(gs[1, 1])  # Третий график занимает вторую ячейку второй строки
    ax3.plot([1, 2, 3], [5, 4, 6])
    ax3.set_title('График 3')

    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    create_gridspec_example()

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

Пример 1: Две графика в первой строке, один — во второй

import matplotlib.pyplot as plt

def example_1() -> None:
  plt.figure(figsize=(8, 6))

  plt.subplot(2, 2, (1,2)) # первая строка, 2 графика вместе
  plt.plot([1, 2, 3], [4, 5, 6])
  plt.title('График 1 и 2')

  plt.subplot(2, 2, 3) # вторая строка, первый график
  plt.plot([1, 2, 3], [6, 5, 4])
  plt.title('График 3')

  plt.subplot(2, 2, 4) # вторая строка, второй график
  plt.plot([1, 2, 3], [5, 4, 3])
  plt.title('График 4')

  plt.tight_layout()
  plt.show()

if __name__ == '__main__':
  example_1()
Реклама

Пример 2: Один график во всю ширину, два — под ним

import matplotlib.pyplot as plt

def example_2() -> None:
    fig = plt.figure(figsize=(10, 6))
    # Создаем объект GridSpec
    gs = plt.GridSpec(2, 2, figure=fig)

    # Первый график занимает всю первую строку
    ax1 = fig.add_subplot(gs[0, :])
    ax1.plot([1, 2, 3], [4, 5, 6])
    ax1.set_title('График 1: Во всю ширину')

    # Второй график занимает левую половину второй строки
    ax2 = fig.add_subplot(gs[1, 0])
    ax2.plot([1, 2, 3], [6, 5, 4])
    ax2.set_title('График 2')

    # Третий график занимает правую половину второй строки
    ax3 = fig.add_subplot(gs[1, 1])
    ax3.plot([1, 2, 3], [5, 4, 3])
    ax3.set_title('График 3')

    plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    example_2()

Пример 3: Сложная компоновка с использованием GridSpec и объединением ячеек

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

def example_3() -> None:
    fig = plt.figure(figsize=(12, 8))
    gs = gridspec.GridSpec(3, 3, figure=fig)

    # Главный график (большой)
    ax1 = fig.add_subplot(gs[0:2, 0:2])  # Занимает первые две строки и первые два столбца
    ax1.plot([1, 2, 3, 4, 5], [5, 4, 3, 2, 1], marker='o')
    ax1.set_title('Главный график')

    # Дополнительный график 1 (справа от главного)
    ax2 = fig.add_subplot(gs[0, 2])  # Первая строка, третий столбец
    ax2.bar([1, 2, 3], [3, 2, 1])
    ax2.set_title('График 2')

    # Дополнительный график 2 (под главным)
    ax3 = fig.add_subplot(gs[1, 2])  # Вторая строка, третий столбец
    ax3.scatter([1, 2, 3], [1, 2, 3])
    ax3.set_title('График 3')

    # График 4 (занимает две ячейки внизу)
    ax4 = fig.add_subplot(gs[2, :])  # Третья строка, все столбцы
    ax4.plot([1, 2, 3, 4, 5], [1, 3, 5, 2, 4], marker='x')
    ax4.set_title('График 4')

    plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    example_3()

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

Использование width_ratios и height_ratios в gridspec_kw при создании подграфиков с помощью plt.subplots() позволяет размещать графики разного размера в строке или столбце. Эти параметры определяют относительные ширины и высоты столбцов и строк сетки, соответственно.

import matplotlib.pyplot as plt

def example_4():
    fig, axes = plt.subplots(1, 2, figsize=(10, 5), gridspec_kw={'width_ratios': [3, 1]})

    # Первый график занимает 3/4 ширины
    axes[0].plot([1, 2, 3], [4, 5, 6])
    axes[0].set_title('Широкий график')

    # Второй график занимает 1/4 ширины
    axes[1].bar([1, 2, 3], [6, 5, 4])
    axes[1].set_title('Узкий график')

    plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    example_4()

Настройка подграфиков

Регулировка расстояния между подграфиками (plt.tight_layout(), hspace, wspace)

Для регулировки расстояния между подграфиками используются:

  • plt.tight_layout(): Автоматически настраивает параметры расположения подграфиков, чтобы обеспечить оптимальное использование пространства и избежать перекрытий.
  • hspace и wspace: Параметры функции plt.subplots_adjust(), позволяющие настроить вертикальное и горизонтальное расстояние между подграфиками в долях от размера осей.

Добавление общих заголовков и подписей к осям

Для добавления общих заголовков и подписей к осям можно использовать методы fig.suptitle() (для заголовка всей фигуры) и fig.text() (для общих подписей осей).

Настройка внешнего вида отдельных подграфиков

Внешний вид каждого подграфика можно настроить индивидуально, используя методы, доступные для объектов Axes. Например, можно изменить цвет, стиль линий, добавить легенду и т.д.

Продвинутые техники и советы

Использование subplot_mosaic для создания сложных макетов с помощью строк

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

import matplotlib.pyplot as plt

def example_mosaic():
    fig, axes = plt.subplot_mosaic([['left', 'right'], ['bottom', 'bottom']], figsize=(8, 6))

    axes['left'].plot([1, 2, 3], [4, 5, 6])
    axes['left'].set_title('Левый график')

    axes['right'].bar([1, 2, 3], [6, 5, 4])
    axes['right'].set_title('Правый график')

    axes['bottom'].scatter([1, 2, 3], [5, 4, 3])
    axes['bottom'].set_title('Нижний график')

    plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    example_mosaic()

Сохранение и загрузка макетов подграфиков

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

Распространенные ошибки и способы их устранения

  • Перекрытие подграфиков: Используйте plt.tight_layout() для автоматической настройки расположения.
  • Неправильная индексация: Убедитесь, что индексы при использовании plt.subplot() соответствуют сетке.
  • Несоответствие размеров: Проверьте соотношение сторон графиков и при необходимости настройте их с помощью gridspec_kw.
  • Нечитаемые подписи: Увеличьте размер шрифта или используйте plt.subplots_adjust() для увеличения пространства между подграфиками.

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