Matplotlib – мощная библиотека для визуализации данных в Python. Одной из распространенных задач является наложение двух графиков, имеющих разные масштабы или единицы измерения по оси Y. Это позволяет сравнивать и анализировать взаимосвязи между различными наборами данных, представленными на одном графике.
Зачем нужны разные оси Y?
Разные оси Y полезны, когда:
- Вы хотите отобразить два набора данных с разными единицами измерения (например, температуру в градусах Цельсия и влажность в процентах).
- Один набор данных имеет значительно больший диапазон значений, чем другой. Использование одной оси Y приведет к тому, что данные с меньшим диапазоном станут практически невидимыми.
- Необходимо визуализировать корреляцию между двумя переменными, измеряемыми в разных масштабах.
Обзор основных подходов к наложению графиков
Основной подход к наложению графиков с разными осями Y в Matplotlib – использование функции twinx(). Она создает вторую ось Y, которая разделяет ось X с исходным графиком. Также можно использовать twiny() для создания второй оси X, хотя это менее распространено.
Использование twinx() для создания второй оси Y
Основы функции twinx()
Функция twinx() создает новый Axes объект, который накладывается поверх существующего. Новая ось Y находится справа, в то время как исходная остается слева. Оба Axes объекта разделяют одну и ту же ось X.
Пример: Наложение графика температуры и влажности
import matplotlib.pyplot as plt
import numpy as np
from typing import List, Tuple
def plot_temperature_humidity(temperature: List[float], humidity: List[float]) -> None:
"""Plots temperature and humidity on the same graph with separate y-axes."""
x = np.arange(len(temperature))
fig, ax1 = plt.subplots()
color = 'tab:red'
ax1.set_xlabel('Время (дни)')
ax1.set_ylabel('Температура (°C)', color=color)
ax1.plot(x, temperature, color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
color = 'tab:blue'
ax2.set_ylabel('Влажность (%)', color=color) # we already handled the x-label with ax1
ax2.plot(x, humidity, color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.title('Температура и влажность')
plt.show()
if __name__ == '__main__':
temperature_data = [20, 22, 25, 23, 21, 24]
humidity_data = [60, 65, 70, 68, 62, 64]
plot_temperature_humidity(temperature_data, humidity_data)
В этом примере:
- Создается основной
Axesобъект (ax1). - На нем рисуется график температуры.
- Вызывается
ax1.twinx(), чтобы создать второйAxesобъект (ax2), разделяющий ось X. - На
ax2рисуется график влажности. - Каждой оси Y назначается свой цвет для лучшей различимости.
Настройка отображения второй оси Y (цвет, метки, деления)
Важно настроить внешний вид второй оси Y, чтобы она не сливалась с первой. Это можно сделать, изменяя цвет, метки и деления оси. В примере выше показано, как изменить цвет метки оси Y с помощью ax2.tick_params(axis='y', labelcolor=color). Аналогично можно настраивать другие параметры отображения.
Более сложные сценарии: twiny() и комбинирование графиков разных типов
Использование twiny() для создания второй оси X (когда это может быть полезно)
Функция twiny() работает аналогично twinx(), но создает вторую ось X, разделяющую ось Y. Это может быть полезно, например, когда вы хотите отобразить одни и те же данные, но с разными единицами измерения по оси X (например, время в секундах и частоту в герцах).
Наложение столбчатой диаграммы и линейного графика с разными осями Y
Можно комбинировать графики разных типов (например, столбчатую диаграмму и линейный график) с разными осями Y. В этом случае важно правильно настроить отображение, чтобы графики не перекрывали друг друга и были легко читаемы.
import matplotlib.pyplot as plt
import numpy as np
def plot_bar_and_line(data1: List[int], data2: List[float], labels: List[str]) -> None:
"""Plots a bar chart and a line graph on the same plot with separate y-axes."""
x = np.arange(len(labels))
fig, ax1 = plt.subplots()
ax1.bar(x, data1, color='skyblue', label='Data 1')
ax1.set_xlabel('Categories')
ax1.set_ylabel('Data 1 Value', color='skyblue')
ax1.tick_params(axis='y', labelcolor='skyblue')
ax2 = ax1.twinx()
ax2.plot(x, data2, color='salmon', marker='o', label='Data 2')
ax2.set_ylabel('Data 2 Value', color='salmon')
ax2.tick_params(axis='y', labelcolor='salmon')
plt.xticks(x, labels)
fig.tight_layout()
# Add legend
lines, labels = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc='upper right')
plt.title('Bar Chart and Line Graph Combination')
plt.show()
if __name__ == '__main__':
categories = ['A', 'B', 'C', 'D', 'E']
bar_data = [10, 15, 13, 18, 20]
line_data = [2.0, 2.5, 3.0, 3.5, 4.0]
plot_bar_and_line(bar_data, line_data, categories)
Решение проблем с видимостью графиков (z-order)
Иногда графики могут перекрываться, затрудняя их чтение. Свойство zorder позволяет контролировать порядок наложения графиков. График с большим значением zorder будет отображаться поверх графика с меньшим значением.
Настройка внешнего вида и улучшение читаемости
Цветовая схема для разделения графиков и осей
Используйте разные цвета для каждого графика и соответствующей оси Y. Это значительно улучшает читаемость графика. Выбор цветов должен быть осознанным, с учетом цветовой слепоты.
Добавление легенды с правильным отображением обеих серий данных
Легенда должна четко указывать, какая линия соответствует какой оси Y. В примере выше показан способ объединения легенд с обеих осей ax1 и ax2.
Использование Grid для облегчения восприятия данных
Сетка (grid) может помочь в оценке значений на графике. Используйте plt.grid(True) для добавления сетки.
Заключение
Преимущества и недостатки использования разных осей Y
Преимущества:
- Возможность отображения данных с разными масштабами и единицами измерения.
- Улучшенное сравнение и анализ взаимосвязей между различными наборами данных.
Недостатки:
- Может ввести в заблуждение, если масштабы осей Y выбраны некорректно.
- Сложность интерпретации для неопытных пользователей.
Когда следует избегать использования разных осей Y
Избегайте использования разных осей Y, если это может исказить представление данных или ввести в заблуждение. В таких случаях лучше использовать отдельные графики или нормализовать данные.