Сетка Matplotlib
Узнайте, как создавать многопанельные макеты и добавлять линии сетки в Matplotlib с помощью subplots, GridSpec, subplot_mosaic и параметров стилизации.
Matplotlib использует слово «сетка» в двух разных значениях: многопанельные макеты (размещение нескольких осей рядом в одной фигуре) и фоновые линии сетки (опорные линии, рисуемые за данными на отдельной оси). Эта глава охватывает оба случая — сначала сеточные макеты, затем стилизацию линий сетки.
Предполагается, что вы уже знакомы с основами построения графиков. Если нет — сначала прочитайте главы Matplotlib Plotting и Matplotlib Subplot.
Многопанельные макеты
Когда нужно отобразить несколько связанных графиков в одной фигуре, их размещают в сетке строк и столбцов. Matplotlib предлагает три подхода, каждый из которых подходит для разного уровня сложности.
plt.subplots() — быстрый способ
plt.subplots(nrows, ncols) — самый быстрый способ для равномерных сеток, в которых все подграфики одного размера. Функция возвращает Figure и массив NumPy объектов Axes.
import matplotlib.pyplot as plt
# 2-row, 2-column grid — four equal subplots
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(8, 6))
axs[0, 0].plot([1, 2, 3], [4, 5, 6])
axs[0, 0].set_title("Line plot")
axs[0, 1].scatter([1, 2, 3], [4, 5, 6])
axs[0, 1].set_title("Scatter plot")
axs[1, 0].bar([1, 2, 3], [4, 5, 6])
axs[1, 0].set_title("Bar chart")
axs[1, 1].hist([1, 2, 3, 4, 5, 6], bins=3)
axs[1, 1].set_title("Histogram")
plt.tight_layout()
plt.show()tight_layout() автоматически регулирует отступы, чтобы заголовки и подписи делений не перекрывались. Параметр figsize=(width, height) задаёт общий размер фигуры в дюймах.
Совместное использование осей
Если графики используют одну шкалу, можно связать их оси, чтобы масштабирование одного отражалось на всех:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 3), sharey=True)
ax1.plot(x, np.sin(x))
ax1.set_title("sin(x)")
ax2.plot(x, np.cos(x))
ax2.set_title("cos(x)")
plt.tight_layout()
plt.show()sharey=True синхронизирует диапазон оси Y в обоих подграфиках; sharex=True делает то же самое для оси X.
GridSpec — ячейки переменного размера
GridSpec позволяет задавать разные веса строкам и столбцам, чтобы одни подграфики были выше или шире других. Также можно растянуть один подграфик на несколько ячеек.
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(9, 6))
# 2 rows, 3 columns; bottom row is twice as tall
gs = GridSpec(nrows=2, ncols=3, height_ratios=[1, 2], hspace=0.4, wspace=0.3)
ax_top_left = fig.add_subplot(gs[0, 0])
ax_top_mid = fig.add_subplot(gs[0, 1])
ax_top_right = fig.add_subplot(gs[0, 2])
ax_bottom = fig.add_subplot(gs[1, :]) # spans all three columns
ax_top_left.plot([0, 1, 2], [0, 1, 0])
ax_top_left.set_title("Top left")
ax_top_mid.bar([0, 1, 2], [3, 1, 4])
ax_top_mid.set_title("Top centre")
ax_top_right.scatter([0, 1, 2], [2, 7, 1])
ax_top_right.set_title("Top right")
ax_bottom.plot([0, 1, 2, 3, 4], [0, 1, 4, 9, 16], color="steelblue", linewidth=2)
ax_bottom.set_title("Bottom — full width")
plt.show()Основные аргументы GridSpec:
| Аргумент | Описание |
|---|---|
width_ratios=[2, 1, 1] | Ширина столбцов в относительных пропорциях |
height_ratios=[1, 2] | Высота строк в относительных пропорциях |
hspace=0.4 | Вертикальный зазор между строками (доля высоты оси) |
wspace=0.3 | Горизонтальный зазор между столбцами (доля ширины оси) |
Срезы gs[row, col] работают так же, как в NumPy: gs[1, :] охватывает все столбцы; gs[:, 0] охватывает все строки первого столбца.
subplot_mosaic() — макет из строки
Появившийся в Matplotlib 3.3, subplot_mosaic() позволяет описать макет с помощью строки или вложенного списка, напоминающего ASCII-карту фигуры. Это зачастую самый читаемый подход для асимметричных макетов.
import matplotlib.pyplot as plt
layout = """
AB
CC
"""
fig, axes = plt.subplot_mosaic(layout, figsize=(8, 5))
axes["A"].set_title("Panel A")
axes["A"].plot([1, 2, 3], [3, 1, 2])
axes["B"].set_title("Panel B")
axes["B"].scatter([1, 2, 3], [2, 3, 1])
axes["C"].set_title("Panel C — full width")
axes["C"].bar(["x", "y", "z"], [5, 3, 7])
plt.tight_layout()
plt.show()Каждая уникальная буква в строке становится отдельным объектом Axes. Повторяющиеся буквы в одной строке/столбце заставляют подграфик занимать эти ячейки. Возвращаемый словарь axes индексируется по метке, поэтому обращение к панелям по имени нагляднее, чем числовая индексация.
Управление отступами: tight_layout и constrained_layout
Два встроенных механизма управляют автоматическими отступами:
plt.tight_layout()— вызывается передplt.show(). Корректирует параметры подграфика, чтобы подписи и заголовки помещались в область. Простой и надёжный для большинства макетов.constrained_layout=True— передаётся вplt.subplots()илиplt.figure(). Решает систему ограничений во время отрисовки; лучше обрабатывает цветовые шкалы и общие заголовки, чемtight_layout.
import matplotlib.pyplot as plt
# constrained_layout keeps the super-title from overlapping the subplots
fig, axs = plt.subplots(1, 2, figsize=(8, 3), constrained_layout=True)
fig.suptitle("Two plots with constrained_layout", fontsize=13)
axs[0].plot([1, 2, 3], [1, 4, 9])
axs[0].set_title("Subplot 1")
axs[1].plot([1, 2, 3], [9, 4, 1])
axs[1].set_title("Subplot 2")
plt.show()Не используйте оба механизма одновременно — они конфликтуют. constrained_layout является более современным вариантом.
Для ручного управления fig.subplots_adjust(left, right, top, bottom, hspace, wspace) полностью переопределяет автоматические отступы.
Фоновые линии сетки
На отдельной оси ax.grid() рисует опорные линии в позициях делений. Это отличается от сеточного макета, описанного выше — линии сетки являются визуальными ориентирами, рисуемыми за данными графика.
Включение линий сетки
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot([1, 2, 3, 4, 5], [2, 5, 3, 8, 6], marker="o")
# Enable gridlines on both axes
ax.grid(True)
ax.set_title("Plot with gridlines")
plt.tight_layout()
plt.show()Стилизация линий сетки
Передайте именованные аргументы в ax.grid(), чтобы изменить внешний вид:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot([1, 2, 3, 4, 5], [2, 5, 3, 8, 6], marker="o", color="steelblue")
ax.grid(
True,
which="major", # "major", "minor", or "both"
axis="both", # "x", "y", or "both"
color="gray",
linestyle="--",
linewidth=0.7,
alpha=0.7,
)
ax.set_title("Styled gridlines")
plt.tight_layout()
plt.show()Основные и вспомогательные линии сетки
Matplotlib различает основные деления (подписанные) и вспомогательные деления (непомеченные подразделения). Линии сетки можно отображать на обоих уровнях:
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot([0, 1, 2, 3, 4, 5, 6], [0, 1, 4, 9, 16, 25, 36])
# Major gridlines every 1 unit, minor every 0.5
ax.xaxis.set_major_locator(MultipleLocator(1))
ax.xaxis.set_minor_locator(MultipleLocator(0.5))
ax.yaxis.set_major_locator(MultipleLocator(10))
ax.yaxis.set_minor_locator(MultipleLocator(5))
ax.grid(True, which="major", linestyle="-", linewidth=0.8, color="gray", alpha=0.6)
ax.grid(True, which="minor", linestyle=":", linewidth=0.5, color="silver", alpha=0.5)
ax.set_title("Major and minor gridlines")
plt.tight_layout()
plt.show()Включение вспомогательных делений без локатора
Если нужно просто отобразить вспомогательные деления без ручного размещения:
ax.minorticks_on()
ax.grid(True, which="both")Стилизация с помощью таблиц стилей Matplotlib
Линии сетки также управляются таблицами стилей. Например, стиль seaborn-v0_8-whitegrid автоматически включает горизонтальные линии сетки:
import matplotlib.pyplot as plt
plt.style.use("seaborn-v0_8-whitegrid")
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot([1, 2, 3, 4], [3, 7, 2, 9], marker="s")
ax.set_title("seaborn-v0_8-whitegrid style")
plt.tight_layout()
plt.show()Выполните plt.style.available, чтобы получить список всех встроенных стилей.
Выбор подходящего инструмента
| Задача | Лучший инструмент |
|---|---|
| Сетка подграфиков одинакового размера | plt.subplots(nrows, ncols) |
| Подграфики разного размера или занимающие несколько ячеек | GridSpec |
| Асимметричный макет, описанный визуально | subplot_mosaic() |
| Опорные линии за данными | ax.grid() |
| Точное размещение делений для линий сетки | MultipleLocator + ax.grid(which=...) |
Связанные главы
- Matplotlib Subplot — подробное рассмотрение
plt.subplots()и объектов осей - Matplotlib Labels — добавление заголовков, подписей осей и аннотаций
- Matplotlib Plotting — линейные графики, столбчатые диаграммы и круговые диаграммы
- Matplotlib Scatter — точечные диаграммы и настройка маркеров