Создание нескольких экземпляров осей на одной фигуре в Matplotlib
Создано: 01.12.2025
До сих пор мы использовали возможности библиотеки Matplotlib в процедурном стиле, то есть для построения графиков вызывали функции. Однако то же самое можно делать, вызывая методы объектов, то есть работать с плотами в объектно-ориентированном стиле. Данный вариант предоставляет дополнительные возможности.
В конце вводного урока про Matplotlib мы разделяли окно на части, в каждой из которых отрисовывался свой график со своими осями. И делали это с помощью функции subplot. При этом подмодуль pyplot так обрабатывал вызовы функции plot(), что график размещался в той части, которая была указана при последнем вызове subplot(). Однако мы могли сразу присваивать части переменным и вызывать plot() уже от них.
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('Правый')
Параметр 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() не передавать количество строк, столбцов и позицию, то экземпляр осей займет всю фигуру. Отметим, что параметр projection возможен и в функции subplot().