Matplotlib: Как построить два графика с общей осью X?

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

Зачем использовать общую ось X?

Общие оси X предоставляют ряд преимуществ:

  1. Улучшенное сравнение данных: Визуальное сравнение различных наборов данных становится интуитивно понятным.
  2. Экономия места: Уменьшается избыточность отображения одинаковой информации об оси X для каждого графика.
  3. Синхронизация взаимодействий: Масштабирование или перемещение по оси X на одном графике автоматически отражается на всех остальных.

Обзор различных подходов к созданию общих осей

Matplotlib предлагает несколько способов создания графиков с общей осью X:

  • plt.subplots() с аргументом sharex=True
  • matplotlib.pyplot.twinx()

Каждый подход имеет свои преимущества и недостатки, которые будут рассмотрены ниже.

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

Основы plt.subplots() и аргумента sharex

Функция plt.subplots() создает фигуру и набор подграфиков (axes). Аргумент sharex=True указывает, что все созданные подграфики должны использовать общую ось X. Это простой и удобный способ для создания нескольких графиков, визуализирующих данные с одним и тем же диапазоном по оси X.

Пример: Два графика с общей осью X, отображающие разные данные

В этом примере мы построим два графика: один отображает динамику цены контекстной рекламы, а другой — количество показов.

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


def create_shared_x_plot(x_data: np.ndarray, y1_data: np.ndarray, y2_data: np.ndarray, title: str) -> Tuple[plt.Figure, plt.Axes, plt.Axes]:
    """Creates two subplots sharing the x-axis.

    Args:
        x_data: X-axis data.
        y1_data: Data for the first subplot.
        y2_data: Data for the second subplot.
        title: The plot title.

    Returns:
        A tuple containing the Figure and both Axes objects.
    """
    fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
    fig.suptitle(title)

    ax1.plot(x_data, y1_data, 'b-', label='Цена клика')
    ax1.set_ylabel('Цена, руб.', color='b')
    ax1.tick_params('y', colors='b')
    ax1.grid(True)

    ax2.plot(x_data, y2_data, 'r-', label='Показы')
    ax2.set_ylabel('Количество показов', color='r')
    ax2.tick_params('y', colors='r')
    ax2.set_xlabel('Время')
    ax2.grid(True)

    fig.tight_layout(rect=[0, 0.03, 1, 0.95]) # Adjust layout to prevent overlapping titles/labels

    return fig, ax1, ax2

# Sample data
x = np.arange(0, 10, 0.1)
price = np.sin(x) + np.random.normal(0, 0.1, len(x))
impressions = np.cos(x) * 100 + np.random.normal(0, 5, len(x))

fig, ax1, ax2 = create_shared_x_plot(x, price, impressions, "Динамика цены клика и показов")

plt.show()

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

Для улучшения читаемости графиков рекомендуется добавлять заголовки, метки осей и легенды. Функция plt.title() задает заголовок для всей фигуры, а ax.set_xlabel(), ax.set_ylabel() и ax.set_title() — для отдельных подграфиков. Используйте fig.tight_layout() для предотвращения перекрытия элементов.

Использование matplotlib.pyplot.twinx() для создания общей оси X

Принцип работы twinx()

Функция twinx() создает новый набор осей, который накладывается на существующий. Новый набор осей имеет общую ось X с исходным, но свою собственную ось Y. Это позволяет отображать два графика с разными шкалами Y на одном и том же графике.

Пример: Наложение двух графиков с разными осями Y и общей осью X

Предположим, нам нужно отобразить количество кликов и CTR (click-through rate) рекламной кампании на одном графике.

Реклама
import matplotlib.pyplot as plt
import numpy as np
from typing import Tuple


def create_twinx_plot(x_data: np.ndarray, clicks_data: np.ndarray, ctr_data: np.ndarray, title: str) -> Tuple[plt.Figure, plt.Axes, plt.Axes]:
    """Creates a plot with two y-axes sharing the x-axis.

    Args:
        x_data: X-axis data.
        clicks_data: Data for the number of clicks.
        ctr_data: Data for the click-through rate.
        title: The plot title.

    Returns:
        A tuple containing the Figure and both Axes objects.
    """
    fig, ax1 = plt.subplots()
    fig.suptitle(title)

    ax1.plot(x_data, clicks_data, 'g-', label='Клики')
    ax1.set_xlabel('Время')
    ax1.set_ylabel('Клики', color='g')
    ax1.tick_params('y', colors='g')
    ax1.grid(True)

    ax2 = ax1.twinx()
    ax2.plot(x_data, ctr_data, 'b-', label='CTR')
    ax2.set_ylabel('CTR (%)', color='b')
    ax2.tick_params('y', colors='b')

    fig.tight_layout()

    return fig, ax1, ax2

# Sample data
x = np.arange(0, 10, 0.1)
clicks = np.random.randint(10, 100, len(x))
ctr = np.sin(x) * 5 + 10 + np.random.normal(0, 1, len(x))

fig, ax1, ax2 = create_twinx_plot(x, clicks, ctr, "Клики и CTR рекламной кампании")

plt.show()

Добавление легенды для различения графиков

Когда используются twinx(), важно добавить легенду, чтобы пользователи могли легко идентифицировать, какой график соответствует какой оси Y. Это можно сделать с помощью ax.legend() для каждого набора осей. Чтобы все легенды были видны, используйте fig.tight_layout().

Ограничения twinx() и альтернативы

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

Продвинутые техники работы с общими осями

Управление тиками и метками общей оси X

Matplotlib предоставляет гибкие инструменты для управления тиками и метками на общей оси X. Можно задавать интервалы тиков, форматировать метки и скрывать ненужные элементы. Используйте ax.set_xticks(), ax.set_xticklabels() и ax.tick_params() для точной настройки.

Синхронизация масштаба осей Y при использовании twinx()

В некоторых случаях может потребоваться синхронизировать масштабы осей Y при использовании twinx(). Это позволяет визуально сравнивать относительные изменения данных. Можно использовать функции ax.get_ylim() и ax.set_ylim() для получения и установки пределов осей.

Обработка перекрывающихся элементов графиков

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

Заключение

Краткий обзор рассмотренных методов

В этой статье мы рассмотрели два основных способа создания графиков с общей осью X в Matplotlib:

  • plt.subplots() с sharex=True: Подходит для создания нескольких графиков с одним и тем же диапазоном по оси X.
  • matplotlib.pyplot.twinx(): Позволяет накладывать два графика с разными осями Y на один график.

Рекомендации по выбору подходящего метода в зависимости от задачи

Выбор метода зависит от конкретной задачи. Если нужно просто сравнить несколько наборов данных с одним и тем же диапазоном по оси X, то plt.subplots() с sharex=True является наиболее простым и удобным вариантом. Если нужно отобразить два набора данных с разными шкалами Y на одном графике, то twinx() может быть подходящим решением.

Дополнительные ресурсы и ссылки для дальнейшего изучения


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