Создание нескольких экземпляров осей на одной фигуре в Matplotlib

Создано: 01.12.2025

До сих пор мы использовали возможности библиотеки Matplotlib в процедурном стиле, то есть для построения графиков вызывали функции. Однако то же самое можно делать, вызывая методы объектов, то есть работать с плотами в объектно-ориентированном стиле. Данный вариант предоставляет дополнительные возможности.

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

Присваивание осей (axes) переменным в Matplotlib
import numpy as np
import matplotlib.pyplot as plt

a = np.linspace(1, 50, 15)

p1 = plt.subplot(2, 1, 1)
p2 = plt.subplot(2, 1, 2)

p1.plot(a, np.sqrt(a))
p2.plot(a, np.power(a,2))

plt.show()

В этом случае plot уже не функция, а метод. Сами переменные связаны с объектами-осями.

print(type(plt.plot))
print(type(p1.plot))
print(p1)
print(type(p1))
<class 'function'>
<class 'method'>
AxesSubplot(0.125,0.53;0.775x0.35)
<class 'matplotlib.axes._subplots.AxesSubplot'>

Вызывать несколько раз subplot неудобно, поэтому чаще выбирают ООП-подход, при котором используется функция subplots. Без аргументов она создает одну фигуру и один экземпляр осей на них, которые займут все окно-фигуру.

fig, ax = plt.subplots()
print(fig)
print(type(fig))
print(ax)
print(type(ax))

a = np.linspace(1, 50, 15)
ax.plot(a, np.sqrt(a))
Figure(640x480)
<class 'matplotlib.figure.Figure'>
AxesSubplot(0.125,0.11;0.775x0.77)
<class 'matplotlib.axes._subplots.AxesSubplot'>

Для разделения окна на части в subplots() передают количество строк и столбцов. В результате вместо одного объекта-осей возвращается массив таковых:

fig, axs = plt.subplots(2, 1)
print(axs, type(axs))
print(axs[0])
print(type(axs[0]))

a = np.linspace(1, 50, 15)
axs[0].plot(a, np.sqrt(a))
axs[1].plot(a, np.power(a, 3))
[<AxesSubplot: > <AxesSubplot: >] <class 'numpy.ndarray'>
AxesSubplot(0.125,0.53;0.775x0.35)
<class 'matplotlib.axes._subplots.AxesSubplot'>

При этом оси массива располагаются на фигуре последовательно. Первая система координат займет первую ячейку, вторая — следующую по горизонтали, или, если "строка" закончена, первую в нижележащем ряду.

С помощью параметра figsize можно указать размер ширины и высоты фигуры.

fig, axs = plt.subplots(figsize=(10, 6.5))

Обратим внимание, что под осями (axes) в Matplotlib понимается отдельно взятая система координат. Это может быть плоскость (координаты x и y), 3D-пространство (x, y, z) или что-то другое. Для простоты мы иногда называем такую отдельно взятую систему координат плотом, подразумевая "полотно", на котором "художник" рисует.

Для более сложного, чем по строкам и столбцам, разделения окна на плоты используется функция subplot_mosaic. Каждый вложенный массив произвольно именует ячейки одной "строки" фигуры. Набор осей возвращается уже не как массив ndarray, а как словарь. Поэтому обращение к каждому плоту происходит по ключу.

fig, axs = plt.subplot_mosaic([['top', 'top'],
                               ['bottom_left', 'bottom_right'],
                               ['bottom_left', 'bottom_right']],
                               layout='constrained')
axs['top'].set_title('Верхний')
axs['bottom_left'].set_title('Левый')
axs['bottom_right'].set_title('Правый')
Пример мозаичного разделение окна с помощью функции subplot_mosaic

Параметр layout со значением 'constrained' заставляет плоты занимать все доступное пространство фигуры. При этом заголовки не перекрывают другие графики, и нет необходимости регулировать размеры осей как-либо иначе.

С помощью функции figure() модуля pyplot фигуру (окно) можно создавать без экземпляров осей. Их создать позже от фигуры с помощью метода add_subplot(). Данный вариант подобен вызову функции subplot() в процедурном стиле и обычно используется для построения графиков в трехмерной системе осей или сочетания в одной фигуре двумерного и трехмерного плотов.

point_type = [('x', 'i2'), ('y', 'f2'), ('z', 'i1'),
              ('color', 'U10'), ('size', 'i2')]
a = np.array([
    (100, 0.8, 90, 'red', 300), (120, 0.3, 48, 'green', 500),
    (200, 0.5, 28, 'orange', 800), (140, 0.1, -50, 'black', 200),
    (180, 0.9, 98, 'blue', 400), (150, 0.5, 25, 'purple', 600)],
     dtype=point_type)

fig = plt.figure()

planeZ = fig.add_subplot(2,2,1)
planeZ.scatter(a['x'], a['y'], s=a['size'], c=a['color'])
planeX = fig.add_subplot(2,2,2)
planeX.scatter(a['y'], a['z'], s=a['size'], c=a['color'])
planeY = fig.add_subplot(2,2,3)
planeY.scatter(a['x'], a['z'], s=a['size'], c=a['color'])

volume = fig.add_subplot(2,2,4, projection='3d')
volume.scatter(a['x'], a['y'], a['z'], s=a['size'], c=a['color'])
Пример разделения окна на части с помощью add_subplot. 2D и 3D системы осей на одной фигуре.

Если в add_subplot() не передавать количество строк, столбцов и позицию, то экземпляр осей займет всю фигуру. Отметим, что параметр projection возможен и в функции subplot().