Почему многие примеры используют "fig, ax = plt.subplots()" в Matplotlib/pyplot/python

Я учусь пользоваться matplotlib изучая примеры, и множество примеров, кажется, включают строку, подобную приведенной ниже, перед созданием одного сюжета...

fig, ax = plt.subplots()

Вот несколько примеров...

Я вижу, что эта функция часто используется, хотя в примере делается попытка создать только один график. Есть ли какое-то другое преимущество? Официальная демоверсия для subplots() также использует f, ax = subplots при создании одного графика, и после этого он ссылается только на топор. Это код, который они используют.

# Just a figure and one subplot
f, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')

6 ответов

Решение

plt.subplots() является функцией, которая возвращает кортеж, содержащий фигуру и объект (ы) осей. Таким образом, при использовании fig, ax = plt.subplots() вы распаковываете этот кортеж в переменные fig а также ax, имеющий fig полезно, если вы хотите изменить атрибуты уровня фигуры или сохранить фигуру в виде файла изображения позже (например, с помощью fig.savefig('yourfilename.png'), Вы, конечно, не должны использовать возвращенный объект figure, но многие люди используют его позже, так что это часто можно увидеть. Кроме того, все объекты осей (объекты, которые имеют методы построения графиков) в любом случае имеют родительский объект figure, таким образом:

fig, ax = plt.subplots()

более кратким, чем это:

fig = plt.figure()
ax = fig.add_subplot(111)

Просто дополнение здесь.

Следующий вопрос заключается в том, что, если я хочу больше участков на рисунке?

Как уже упоминалось в документе, мы можем использовать fig = plt.subplots(nrows=2, ncols=2) установить группу участков с сеткой (2,2) в одном фигурном объекте.

Тогда, как мы знаем, fig, ax = plt.subplots() возвращает кортеж, давайте попробуем fig, ax1, ax2, ax3, ax4 = plt.subplots(nrows=2, ncols=2) во-первых.

ValueError: not enough values to unpack (expected 4, got 2)

Это вызывает ошибку, но не беспокойтесь, потому что теперь мы видим, что plt.subplots() на самом деле возвращает кортеж с двумя элементами. Первый должен быть объектом рисунка, а другой должен быть группой объектов подзаговоров.

Итак, давайте попробуем это снова:

fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(nrows=2, ncols=2)

и проверьте тип:

type(fig) #<class 'matplotlib.figure.Figure'>
type(ax1) #<class 'matplotlib.axes._subplots.AxesSubplot'>

Конечно, если вы используете параметры как (nrows=1, ncols=4), то формат должен быть:

fig, [ax1, ax2, ax3, ax4] = plt.subplots(nrows=1, ncols=4)

Так что просто помните, что построение списка должно быть таким же, как и для сетки подзаговоров, которую мы установили на рисунке.

Надеюсь, это будет полезно для вас.

В дополнение к вопросу и ответам выше, есть также важное различие между plt.subplots() а также plt.subplot() обратите внимание на пропавшие 's' в конце.

Можно использовать plt.subplots() чтобы сделать все их подзаговоры одновременно, и он возвращает фигуру и оси (во множественном числе от оси) подзаговоров в виде кортежа. Фигуру можно понимать как холст, на котором вы рисуете свой эскиз.

# create a subplot with 2 rows and 1 columns
fig, ax = plt.subplots(2,1)

Принимая во внимание, что вы можете использовать plt.subplot() если вы хотите добавить субплоты отдельно. Возвращает только ось одного субплота.

fig = plt.figure() # create the canvas for plotting
ax1 = plt.subplot(2,1,1) 
# (2,1,1) indicates total number of rows, columns, and figure number respectively
ax2 = plt.subplot(2,1,2)
ax3 = plt.subplot(2,1,3) 

Тем не мение, plt.subplots() предпочтительнее, потому что это дает вам более простые возможности напрямую настроить всю фигуру

# for example, sharing x-axis, y-axis for all subplots can be specified at once
fig, ax = plt.subplots(2,1, sharex=True, sharey=True)

тогда как, с plt.subplot() Для каждой оси нужно указать индивидуально, что может стать громоздким.

В дополнение к ответам выше, вы можете проверить тип объекта, используя type(plt.subplots()) который возвращает кортеж, с другой стороны, type(plt.subplot()) возвращается matplotlib.axes._subplots.AxesSubplot который вы не можете распаковать.

С использованием plt.subplots() популярен, потому что он дает вам объект Axes и позволяет использовать интерфейс Axes для определения графиков.

Альтернативой было бы использование интерфейса глобального состояния, plt.plot и т. д. функциональность:

      import matplotlib.pyplot as plt

# global state version - modifies "current" figure
plt.plot(...)
plt.xlabel(...)

# axes version - modifies explicit axes
ax.plot(...)
ax.set_xlabel(...)

Так почему мы предпочитаем топоры?

  • Его можно отредактировать - вы можете поместить часть кода в функцию, которая принимает объект Axes и не полагается на глобальное состояние.
  • Легче перейти к ситуации с несколькими подсюжетами
  • Один последовательный / знакомый интерфейс вместо переключения между двумя
  • Единственный способ получить доступ ко всем функциям matplotlib

Версия с глобальным состоянием была создана таким образом, чтобы ее было легко использовать в интерактивном режиме и чтобы она была знакомым интерфейсом для пользователей Matlab, но в более крупных программах и сценариях отмеченные здесь моменты благоприятствуют использованию интерфейса Axes.

В блоге matplotlib есть сообщение, в котором эта тема исследуется более подробно: Pyplot vs объектно-ориентированный интерфейс

Относительно легко иметь дело с обоими мирами. Например, мы всегда можем запросить текущие оси: ax = plt.gca() ("получить текущие оси").

fig.tight_layout()

такая возможность очень удобна, если xticks_labels выходит за пределы окна графика, то такая линия помогает подогнать xticks_labels и весь график под окно, если автоматическое позиционирование графика в plt-окне работает некорректно. И эта строка кода работает, только если вы используете fig-object в plt-окне

      fig, ax = plt.subplots(figsize=(10,8))

myData.plot(ax=ax)
plt.xticks(fontsize=10, rotation=45)

fig.tight_layout()
plt.show()
Другие вопросы по тегам