Статьи
September 28, 2022

Руководство по subplots в matplotlib

Если вы полезли в аналитику, то, вероятно, обнаружили, что там много, ну ОЧЕНЬ МНОГО графиков. Иногда хватает одного, и тогда всё отлично. А если нужно два? А если пять? И рядом. Тут поможет matplotlib.

В этом материале обсудим функцию subplot библиотеки matplotlib в Python, которая позволяет работать с несколькими графиками, а также рассмотрим следующие моменты:

Функция subplot

В библиотеке matplotlib можно создать несколько графиков в рамках одной сетки, при этом кастомизировать каждый график по отдельности. Для этого в Python используется функция matplotlib.pyplot.subplot().

Синтаксис следующий:

matplotlib.pyplot.subplot(nrows, ncols, idx [, label, projection, ...])

где:

  • nrows задает количество строк в сетке;
  • ncols задает количество столбцов в сетке отрисовки;
  • idx задает индексное положение участка на сетке. Индекс начинается с 1 в левом верхнем углу и увеличивается вправо.
  • idx также может быть задан как кортеж из двух целых чисел, указывающих первый и последний индексы, включая последний индекс в сетке. Например, subplots(6, 2, (1, 4)) заполнит верхнюю треть (или 4/6) на сетке.

Есть и другие необязательные параметры, такие как label, projection, sharex, sharey, polar и т.д.

ПРИМЕЧАНИЕ: в matplotlib.pyplot.subplot() можно передать и трёхзначное целое число, оно будет представлять собой 3 параметра. Например, matplotlib.pyplot.subplot(437) — это то же самое, что matplotlib.pyplot.subplot(4, 3, 7). Создаётся сетка на 4 строки и 3 столбца, и график добавляется в 1-й столбец 3-й строки (по 7-му индексу).

Давайте приступим к практике:

# импортируем необходимые библиотеки
import matplotlib.pyplot as plt
import numpy as np

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g')

# график 2
plt.subplot(2, 2, 2)
plt.plot(x, y2, '-.r')

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, ':y')

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--c')

plt.show()
Графики в matplotlib

Регулировка размера сетки

Мы можем настроить размер сетки с визуализациями, указав список из двух значений в параметре figsize функции matplotlib.pyplot.figure(), где первое значение задает ширину сетки, а второе — высоту.

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# изменяем размер сетки
plt.figure(figsize=[9, 7])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)

plt.show()
Регулировка размера отрисовки

Добавление заголовка ко всей сетке

Мы можем сделать заголовок всей сетке, содержащей графики, указав соответствующий текст в функции matplotlib.pyplot.suptitle().

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# изменяем размер отрисовки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок
plt.suptitle('Different degree curves')

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)

plt.show()
Добавление заголовка к отрисовке

Добавление заголовков к отдельным графикам

Мы также можем дать название графикам на сетке, указав текст заголовка на этапе построения каждого из них:

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np
   
# изменяем размер отрисовки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок
plt.suptitle('Different degree curves')

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve') # заголовок графика

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve') # заголовок графика

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve') # заголовок графика

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve') # заголовок графика

plt.show()
Добравление заголовков к каждому графику

Регулировка размера шрифта заголовка

Мы можем задать размер шрифта для текста заголовка (как общий, для сетки, так и частный, для каждого графика) с помощью параметра fontsize:

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np
   
# изменяем размер сетки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок, задаём размер шрифта
plt.suptitle('Different degree curves', fontsize=19)

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15) # заголовок + шрифт

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15) # заголовок + шрифт

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15) # заголовок + шрифт

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', fontsize=15) # заголовок + шрифт

plt.show()
Регулировка размера шрифта заголовка

Выделение заголовка полужирным шрифтом

Мы можем сделать шрифт заголовка жирным (как общий, для сетки, так и частный, для каждого графика), добавив параметр fontweight с нужным целочисленным значением (600+ для жирного шрифта) или строку 'bold':

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# изменяем размер сетки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок, задаём размер шрифта и выделяем его
plt.suptitle('Different degree curves', fontsize=19, fontweight='bold')

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15)

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15)

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15)

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', fontsize=15)

plt.show()
Выделение заголовка полужирным шрифтом

Выставление позиции заголовка

Мы можем задать положение текста заголовка, передав еще два параметра x и y. Эти значения представляют собой координаты сетки x и y соответственно:

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# изменяем размер сетки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок, задаём размер шрифта, выделяем его и позиционируем
plt.suptitle('Different degree curves', x=0.5, y=0, fontsize=17, fontweight='700')

# строим графики
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', loc='left', fontsize=15)

plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', loc='right', fontsize=15)

plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', loc='left', fontsize=15)

plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', loc='right', fontsize=15)

plt.show()
Выставление позиции заголовка

Отступы в заголовках

Мы можем настроить отступы, использовав параметр У, либо параметр pad. В y — координата в сетке (значение варьируется от 0 до 1), в pad — отступ текста заголовка от графика:

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# изменяем размер сетки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок
plt.suptitle('Different degree curves', y=1.1, fontsize=19, fontweight='bold')

# строим графики
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, y=1.1)

plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, y=1.1)

plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)

plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', fontsize=15, pad=17)

plt.show()
Отступы в заголовках

Добавление легенды

Добавить легенду можно с помощью параметра label и метода legend:

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# изменяем размер сетки
plt.figure(figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# добавляем общий заголовок
plt.suptitle('Different degree curves', y=1.1, fontsize=19, fontweight='bold')

# строим графики
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2, label='1st degree curve')
plt.title('Plot 1: 1st Degree curve', fontsize=15, y=1.1)
plt.legend(loc='upper left')

plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k', label='2nd degree curve')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, y=1.1)
plt.legend(loc='upper left')

plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3, label='3rd degree curve')
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)
plt.legend(loc='upper left')

plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3, label='4th degree curve')
plt.title('Plot 4: 4th Degree curve', fontsize=15, pad=17)
plt.legend(loc='upper left')

plt.show()
Добавление легенды

В matplotlib мы также можем добавить легенду, которая будет общей для всех графиков. Построим их, определив оси и сетку с помощью subplots() и определим глобальную легенду для отрисовки с помощью figure.legend() со следующими параметрами:

  • список всех объектов графика (line2D) (здесь, кривые), которые мы хотим добавить в легенду.
  • lables: Список меток для каждого объекта графика (кривой).
  • loc: местоположение легенды (необязательно).
  • title: заголовок легенды (необязательно).
# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# определяем сетку и оси с помощью matplotlib.pyplot.subplots()
fig, ax = plt.subplots(2, 2, figsize=[11, 9])

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

fig.suptitle('Different degree curves', fontsize=19, fontweight='bold')

# строим графики
c1 = ax[0,0].plot(x, y1, 'g', linewidth=2)
ax[0,0].set_title('Plot 1', fontsize=15)

c2 = ax[0,1].scatter(x, y2, color='k')
ax[0,1].set_title('Plot 2', fontsize=15)

c3 = ax[1,0].plot(x, y3, '-.y', linewidth=3)
ax[1,0].set_title('Plot 3', fontsize=15)

c4 = ax[1,1].plot(x, y4, '--b', linewidth=3)
ax[1,1].set_title('Plot 4', fontsize=15)

label_list = ['1st degree curve', '2nd degree curve', '3rd degree curve', '4th degree curve']

fig.legend([c1, c2, c3, c4],
           labels=label_list,
           loc='upper left',
           borderaxespad=0.1)

plt.show()

Общие оси графиков

Можно построить графики так, чтобы у них была либо одна, либо две общие оси. Для этого в параметрах sharex и sharey нужно выставить значение True. Ось У нельзя сделать общей для графиков по вертикали, Х — по горизонтали.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)
y1 = x + 3
y2 = x + 9
y3 = x + 13
y4 = x + 17

fig, ax = plt.subplots(2, 2, figsize=[11, 9])

fig.suptitle('Different degree curves', fontsize=19, fontweight='bold')

ax[0,0].plot(x, y1, 'g', linewidth=2)
ax[0,0].set_title('Plot 1: 1st degree curve', fontsize=15)

ax[0,1].scatter(x, y2, color='k')
ax[0,1].set_title('Plot 2: 2nd degree curve', fontsize=15)

ax[1,0].plot(x, y3, '-.y', linewidth=3)
ax[1,0].set_title('Plot 3: 3rd degree curve', fontsize=15)

# Plot 4
ax[1,1].plot(x, y4, '--b', linewidth=3)
ax[1,1].set_title('Plot 4: 4th degree curve', fontsize=15)

plt.show()

# ---------------------------------------------------------------------

fig, ax = plt.subplots(2, 2, sharex=True, sharey=True, figsize=[11, 9])

fig.suptitle('Different degree curves', fontsize=19, fontweight='bold')

ax[0,0].plot(x, y1, 'g', linewidth=2)
ax[0,0].set_title('Plot 1: 1st degree curve', fontsize=15)

ax[0,1].scatter(x, y2, color='k')
ax[0,1].set_title('Plot 2: 2nd degree curve', fontsize=15)

ax[1,0].plot(x, y3, '-.y', linewidth=3)
ax[1,0].set_title('Plot 3: 3rd degree curve', fontsize=15)

ax[1,1].plot(x, y4, '--b', linewidth=3)
ax[1,1].set_title('Plot 4: 4th degree curve', fontsize=15)

plt.show()

Подписи для общих осей

В matplotlib нет прямого метода добавления подписи для общей оси, но мы всё-таки можем это сделать.

  • создадим сетку с графиками;
  • с помощью функции figure.add_subplot() добавим ось размером с сетку, в которую будут заключены все графики;
  • отключим отображения значений на осях этого нового графика и будем показывать только метки осей. Это можно сделать, указав параметры labelcolor="none", bottom=False и left=False функции tick_param();
  • теперь мы можем добавить метки оси x и оси y на этот увеличенный график.
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)
y1 = x + 3
y2 = x + 9
y3 = x + 13
y4 = x + 17

fig, ax = plt.subplots(2, 2, figsize=[11, 9])

fig.suptitle('Different degree curves', fontsize=19, fontweight='bold')

ax[0,0].plot(x, y1, 'g', linewidth=2)
ax[0,0].set_title('Plot 1: 1st degree curve', fontsize=15)

ax[0,1].scatter(x, y2, color='k')
ax[0,1].set_title('Plot 2: 2nd degree curve', fontsize=15)

ax[1,0].plot(x, y3, '-.y', linewidth=3)
ax[1,0].set_title('Plot 3: 3rd degree curve', fontsize=15)

ax[1,1].plot(x, y4, '--b', linewidth=3)
ax[1,1].set_title('Plot 4: 4th degree curve', fontsize=15)

fig.add_subplot(1, 1, 1, frame_on=False)

plt.tick_params(labelcolor="none", bottom=False, left=False)

plt.xlabel('Common X-Axis', fontsize=15, fontweight='bold')
plt.ylabel('Common Y-Axis', fontsize=15, fontweight='bold')

plt.show()

Также создать сетку с общими метками осей для всех колонок визуализаций на ней.

# готовим данные для построения графиков
x = np.linspace(0, 10, 10)
y1 = x + 3
y2 = x + 9
y3 = x + 13
y4 = x + 17

# определяем сетку и оси с помощью matplotlib.pyplot.subplots(),
# указываем совместное использование оси x и оси y для графиков
fig, ax = plt.subplots(2, 2, sharex=True, sharey=True, figsize=[11, 9])

fig.suptitle('Different degree curves', fontsize=19, fontweight='bold')

# строим графики
# график 1
ax[0,0].plot(x, y1, 'g', linewidth=2)
ax[0,0].set_title('Plot 1: 1st degree curve', fontsize=15)

# график 2
ax[0,1].scatter(x, y2, color='k')
ax[0,1].set_title('Plot 2: 2nd degree curve', fontsize=15)

# график 3
ax[1,0].plot(x, y3, '-.y', linewidth=3)
ax[1,0].set_title('Plot 3: 3rd degree curve', fontsize=15)

# график 4
ax[1,1].plot(x, y4, '--b', linewidth=3)
ax[1,1].set_title('Plot 4: 4th degree curve', fontsize=15)

# добавляем график на сетку, 
# он будет включать в себя все подграфики, но отображаться будут только оси
fig.add_subplot(1, 1, 1, frame_on=False)

# убираем тики и их метки с большого графика
plt.tick_params(labelcolor="none", bottom=False, left=False)

# добавляем оси на большой график
plt.xlabel('X-Axis', fontsize=15, fontweight='bold')
plt.ylabel('Y-Axis', fontsize=15, fontweight='bold')

plt.show()

Регулировка расстояния между графиками

Можно настроить расстояние между графиками, добавив функцию matplotlib.pyplot.subplots_adjust() с соответствующими значениями параметров. Параметры могут быть следующие:

  • top: указывает верх (верхнюю часть) графика;
  • bottom: указывает низ (нижнюю часть) графика;
  • left: указывает левую сторону графика;
  • right: указывает правую сторону вложенных участков сетки;
  • wspace: указывает ширину, которая должна быть зарезервирована для пустого пространства между графиками;
  • hspace: указывает высоту, которая должна быть зарезервирована для пустого пространства между графиками;
# меняем размер отрисовки
plt.figure(figsize=[11, 9])

# готовим данные
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

plt.suptitle('Different degree curves', 
             y=1.13, 
             fontsize=19, 
             fontweight='bold')

plt.subplots_adjust(left=0.13, 
                    right=0.93, 
                    top=1.0, 
                    bottom= 0.27, 
                    wspace= 0.3, 
                    hspace=0.3)

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, y=1.1)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, y=1.1)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

plt.show()

Автоподбор отступов

В matplotlib есть способ автоматически регулировать расстояние между графиками в зависимости от размеров сетки. Просто нужно добавить функцию matplotlib.pyplot.tight_layout().

Мы также можем задать дополнительный отступ, указав параметры pad, w_pad, h_pad — они задают дополнительные отступы вокруг границы сетки и между графиками. Значения их параметров задаются в виде доли размера шрифта.

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# готовим данные
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

plt.suptitle('Different degree curves', 
              y=1.13, 
              fontsize=19, 
              fontweight='bold')

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, y=1.1)

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, y=1.1)

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', fontsize=15, pad=17)

plt.show()

# ---------------------------------------------------------------------

# строим графики с автоподбором отступа
plt.suptitle('Different degree curves', 
              y=1.13, 
              fontsize=19, 
              fontweight='bold')
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, y=1.1)

# график 2
plt.subplot(2, 2, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, y=1.1)

# график 3
plt.subplot(2, 2, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)

# график 4
plt.subplot(2, 2, 4)
plt.plot(x, y4, '--b', linewidth=3)
plt.title('Plot 4: 4th Degree curve', fontsize=15, pad=17)

plt.tight_layout()
plt.show()

Графики разного размера

Можем создать сетку с графиками разного размера. Для этого нужно разделить сетку на секции, а эти секции — ещё на секции и так далее. На примере нагляднее:

# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# подготавливаем данные
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3

# меняем размер сетки
plt.figure(figsize=[11, 9])

plt.suptitle('Different degree curves', 
             y=1.05, 
             fontsize=19, 
             fontweight='bold')

# строим графики
# график 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 2
plt.subplot(2, 2, 3)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 3
plt.subplot(1, 2, 2)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

plt.tight_layout()
plt.show()
# импортируем библиотеки
import matplotlib.pyplot as plt
import numpy as np

# готовим данные
x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

# меняем размер сетки
plt.figure(figsize=[11, 9])

plt.suptitle('Different degree curves', 
              y=1.05, 
              fontsize=19, 
              fontweight='bold')

# строим графики
# график 1
plt.subplot(3, 1, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 2
plt.subplot(3, 2, 3)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 3
plt.subplot(3, 2, 4)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

# график 4
plt.subplot(3, 1, 3)
plt.plot(x, y4, ':r', linewidth=2)
plt.title('Plot 4: 4th Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')

plt.tight_layout()
plt.show()

Настройка геометрии сетки

Мы можем настраивать макет с помощью функции gridspec и задать геометрию сетки отрисовки, на которой будут размещены графики. Для этого нужно указать количество строк и количество столбцов сетки. Также можно настроить параметры расположения графиков, например, left, right, bottom и т.д.

Синтаксис функции gridspec следующий:

from matplotlib import pyplot as plt
from matplotlib import gridspec

fig = plt.figure()

grid_obj = gridspec.GridSpec(nrows, ncols[, figure, left, 
                             bottom, right, top, wspace, hspace, ...])

ax1 = fig.add_subplot(grid_obj[0, 0])
ax2 = fig.add_subplot(grid_obj[0, 1])
...
...
...
axN = fig.add_subplot(grid_obj[nrows-1, ncols-1])

Функция gridspec.GridSpec() используется для создания сетки из n строк и n столбцов. Параметры функции:

  • nrows: задает количество строк в сетке.
  • ncols: задает количество rколонок в сетке.
  • figure: указывает фигуру (отрисовку), на которой будут размещены сетки. Она необязательна и по умолчанию равна None.
  • left, bottom, right и top: необязательные параметры, определяющие размер графиков в долях ширины и высоты фигуры. При этом левая часть не может быть больше правой, а нижняя часть не может быть больше верхней.
  • wspace и hspace: необязательные параметры, определяющие отступы между графиками, задаются в долях от средней ширины и высоты оси соответственно.
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)
y1 = x + 3
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

fig = plt.figure(constrained_layout=True)
spec = gridspec.GridSpec(ncols=2, nrows=2, figure=fig)

ax1 = fig.add_subplot(spec[0, 0])
ax1.plot(x, y1, 'g', linewidth=2)
ax1.set_title('Plot 1: 1st degree curve', fontsize=15)

ax2 = fig.add_subplot(spec[0, 1])
ax2.scatter(x, y2, color='k')
ax2.set_title('Plot 2: 2nd degree curve', fontsize=15)

ax3 = fig.add_subplot(spec[1, 0])
ax3.plot(x, y3, '-.y', linewidth=3)
ax3.set_title('Plot 3: 3rd degree curve', fontsize=15)

ax4 = fig.add_subplot(spec[1, 1])
ax4.plot(x, y4, '--b', linewidth=3)
ax4.set_title('Plot 4: 4th degree curve', fontsize=15)

plt.show()

Теперь используем gridspec() с графиками разного размера.

x = np.linspace(0, 10, 10)
y = []
y.append(x + 3)
y.append(x ** 2)
y.append(x ** 3)
y.append(x ** 4)

l_style = ['-', ':', '-.', '--']
l_color = ['g', 'k', 'y', 'b']
k = 0

fig2 = plt.figure(figsize=[7, 5], constrained_layout=True)
widths = [1.5, 3]
heights = [2, 3]
spec2 = fig2.add_gridspec(ncols=2, nrows=2, width_ratios=widths,
                          height_ratios=heights)
for row in range(2):
    for col in range(2):
        ax = fig2.add_subplot(spec2[row, col])
        ax.plot(x, y[k], color=l_color[k], linestyle=l_style[k],
                linewidth=3)
        ax.set_title('Plot'+str(k+1)+' : '+str(k+1)+' degree curve',
                     fontsize=15)
        k += 1

plt.show()

Добавление направляющих

Для каждого из графиков на макете можно задать направляющие:

# без направляющих
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3

plt.figure(figsize=[11, 5])

plt.suptitle('Different degree curves', 
              y=1.13, 
              fontsize=19, 
              fontweight='bold')

plt.subplot(1, 3, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.grid()

plt.subplot(1, 3, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.grid()

plt.subplot(1, 3, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.grid()

plt.tight_layout()
plt.show()

# ---------------------------------------------------------------------

# с направляющими
plt.figure(figsize=[11, 11])

plt.suptitle('Different degree curves', 
              y=1.13, 
              fontsize=19, 
              fontweight='bold')

plt.subplot(3, 1, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.grid()

plt.subplot(3, 1, 2)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.grid()

plt.subplot(3, 1, 3)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=17)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.grid()

plt.tight_layout()
plt.show()

Регулировка шага направляющих

Мы можем настроить расстояние между направляющими, увеличив значения xticks и yticks (функции xlim() и ylim() соответственно):

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3

plt.figure(figsize=[11, 9])

plt.suptitle('Different degree curves', 
              y=1.05, 
              fontsize=19, 
              fontweight='bold')

# добавим xlim() и ylim() к каждому графику
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.xlim(0, 12)
plt.ylim(0, 12)
plt.grid()

plt.subplot(2, 2, 3)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.xlim(0, 15)
plt.ylim(0, 150)
plt.grid(alpha=0.8)

plt.subplot(1, 2, 2)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.xlim(0, 15)
plt.ylim(0, 1500)
plt.grid(alpha=0.6)

plt.tight_layout()
plt.show()

Регулировка цвета направляющих

Цвет направляющих тоже можно менять — добавим параметр color со значением в виде названия цвета, либо его кода.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 10)
y1 = x
y2 = x ** 2
y3 = x ** 3

plt.figure(figsize=[11, 9])

plt.suptitle('Different degree curves', 
              y=1.05, 
              fontsize=19, 
              fontweight='bold')

# разукрашиваем направляющие
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'g', linewidth=2)
plt.title('Plot 1: 1st Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis', fontsize=13)
plt.ylabel('Y-Axis', fontsize=13)
plt.xlim(0, 12)
plt.ylim(0, 12)
plt.grid(color='red', linestyle='-.', linewidth=1)

# график 2
plt.subplot(2, 2, 3)
plt.scatter(x, y2, color='k')
plt.title('Plot 2: 2nd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis', fontsize=13)
plt.ylabel('Y-Axis', fontsize=13)
plt.xlim(0, 15)
plt.ylim(0, 150)
plt.grid(alpha=0.8, color='blue', linestyle=':', linewidth=1.2)

# график 3
plt.subplot(1, 2, 2)
plt.plot(x, y3, '-.y', linewidth=3)
plt.title('Plot 3: 3rd Degree curve', fontsize=15, pad=12)
plt.xlabel('X-Axis', fontsize=13)
plt.ylabel('Y-Axis', fontsize=13)
plt.xlim(0, 15)
plt.ylim(0, 1500)
plt.grid(alpha=0.6, color='green', linestyle='--', linewidth=1.4)

plt.tight_layout()
plt.show()
получен навык дезигнер

Добавление изображений на график

Также в качестве графиков можно использовать изображения, которые хранятся у вас на локальном диске, с помощью модуля matplotlib.image. Функция matplotlib.image.imread() импортирует и считывает файл. В качестве аргумента необходимо указать строку, содержащую путь к файлу, а затем его имя. Функция axes.imshow() построит график с изображением на указанных осях.

import matplotlib.pyplot as plt

import matplotlib.image as img
import random
import os

cwd = os.getcwd()
source_path = cwd + '\\image_data\\'

fig, ax = plt.subplots(2,2)
plt.suptitle('Random Images', y=1.05, fontsize=19, fontweight='bold')

for i in range(2):
    for j in range(2):
        image_file = random.choice(os.listdir(source_path))
        image_path = os.path.join(source_path, image_file)
        image = img.imread(image_path)
        
        ax[i,j].set_title(image_file, fontsize=15, pad=12)
        ax[i,j].imshow(image)
        ax[i,j].grid()

plt.tight_layout()
plt.show()

# ------------------------------------------------------------------

plt.figure()
plt.suptitle('Random Images', y=1.05, fontsize=19, fontweight='bold')

for i in range(4):
    image_file = random.choice(os.listdir(source_path))
    image_path = os.path.join(source_path, image_file)
    image = img.imread(image_path)
    
    plt.subplot(2, 2, i+1)
    plt.title(image_file, fontsize=15, pad=12)
    plt.imshow(image)

plt.tight_layout()
plt.show()
получен навык главный дезигнер

Регулировка размера изображений

Регулировать размер изображения можно, изменяя размер сетки, с помощью функции matplotlib.pyplot.figure() с аргументом figsize. Он принимает список из двух значений: ширину и высоту сетки.

import matplotlib.pyplot as plt

import matplotlib.image as img
import random
import os

cwd = os.getcwd()
source_path = cwd + '\\image_data\\'

plt.figure(figsize=[7, 7])
plt.suptitle('Random Images', y=1.05, fontsize=19, fontweight='bold')

for i in range(4):
    image_file = random.choice(os.listdir(source_path))
    image_path = os.path.join(source_path, image_file)
    image = img.imread(image_path)
    
    plt.subplot(2, 2, i+1)
    plt.title(image_file, fontsize=15, pad=12)
    plt.imshow(image)
    plt.grid()

plt.tight_layout()
plt.show()

Добавление цветовой шкалы

Создадим изображения в виде цветовой шкалы и добавим отдельные оси, используя функцию matplotlib.figure.Figure.add_axes() с параметром в виде списка из 4-х значений [left, bottom, width, height]. Параметр mappable функции matplotlib.figure.Figure.colorbar() представляет собой объект графика, цвета которого должны быть отображены в цветовой панели, параметр cax представляет собой оси, на которых должна быть нарисована цветовая панель.

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(2, 2, figsize=[7, 7])

for x in ax.flat:
    image = x.imshow(np.random.random((15,15)), vmin=0, vmax=1)

fig.subplots_adjust(right=0.8)
color_bar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(image, cax=color_bar_ax)

plt.show()

3D-графики

Подмодуль mpl_toolkits.mplot3d.axes3d используется для создания трёх осей и построения графиков трёхмерных фигур. Добавим оси с помощью функции figure.add_subplot() с дополнительным параметром projection='3d', затем создадим 3D-график и добавим его к этим осям.

Описанный выше метод работает и для создания нескольких графиков, просто добавьте на сетку больше осей с 3D-фигурами.

import matplotlib.pyplot as plt
import numpy as np

from matplotlib import cm    # для цветовой шкалы
from mpl_toolkits.mplot3d.axes3d import get_test_data


fig = plt.figure(figsize=[9, 4])

plt.suptitle('3D plots', y=1.05, fontsize=19, fontweight='bold')

# график 1
# задаём оси
ax = fig.add_subplot(1, 2, 1, projection='3d')

# строим 3D-график
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)

R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

surface_pl = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                             cmap=cm.coolwarm, linewidth=0)
ax.set_zlim(-1.01, 1.01)

fig.colorbar(surface_plt, shrink=0.5, aspect=10)
ax.set_title('A 3D Surface')
ax.set_xlabel('X-Axis')
ax.set_ylabel('Y-Axis')
ax.set_zlabel('Z-Axis')


# график 2
# задаём оси
ax = fig.add_subplot(1, 2, 2, projection='3d')

# строим 3D-каркас графика
X, Y, Z = get_test_data(0.05)
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)

ax.set_title('A 3D Wireframe')
ax.set_xlabel('X-Axis')
ax.set_ylabel('Y-Axis')
ax.set_zlabel('Z-Axis')

plt.tight_layout()
plt.show()

Заключение

Если вы дошли сюда сами, пешком и без fast travel, то вы... очень любите графики. Странной неестественной любовью. Верим, что это любовь взаимна :)

Источник: PythonGuides
Перевод и адаптация: Екатерина Прохорова

PythonTalk в Telegram

Чат PythonTalk в Telegram

Предложить материал | Поддержать канал