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

267

Я учусь использовать 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')
neelshiv
источник
11
ну, это коротко, кратко, и вы получите ссылку два и рисунок и ось за один шаг. Это питон, потому что это красиво :)
чел.

Ответы:

325

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)
jonchar
источник
8
Очень хорошее объяснение. Вот документ на нем - matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplots
bretcj7
2
Почему мы всегда используем 111 в качестве параметра в подзаговоре?
Прияньш
@Priyansh, потому что он унаследован от синтаксиса Matlab
pcko1
@Priyansh Не всегда. Если вы хотите 4 графика, вы можете ax11, ax12, ax21, ax22использовать fig.add_subplot(221)(или 222, 223, 224 соответственно).
Гимут
49

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

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

Как уже упоминалось в документе, мы можем использовать 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)

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

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

Duskash
источник
2
не забудьте добавить plt.tight_layout (), если ваши подсюжеты имеют заголовки
gota
12
Что делать, если у вас есть много участков? Проще сделать это так: fig, axes = plt.subplots(nrows=10, ncols=3)и axes = axes.flatten(). Теперь вы можете обратиться к каждому подзаговоре по его индексу: axes[0], axes[1], ...
Гийом
Что, если я хочу, чтобы один из этих подзаговоров охватывал несколько столбцов или строк? это выполнимо с командой subplots?
Гота
1
@BallpointBen Я не уверен, что работает, если nrows=1, как тогда axes, возвращается плоский с длиной, равнойncols
Бен
1
@BallpointBen Просто понял, что это можно исправить, выполнив:fig, axes = plt.subplots(nrows=1, ncols=3, squeeze=False)
Бен
15

В качестве дополнения к вопросу и ответам выше, есть также важное различие между 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)

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

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

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

Light_B
источник
1
Ваша строка кода ax3 = plt.subplot(2,1,3) не будет работать, потому что это 2 на 1, которая имеет только 2 графика.
Облако Чо
1
спасибо, исправил это. В последнем блоке кода было необходимо другое изменение.
Light_B
3

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

Джон Т
источник
4
Добро пожаловать в стек переполнения! Это действительно комментарий, а не ответ. С немного большим количеством повторений вы сможете оставлять комментарии . Спасибо!
Мирослав Гламузина