Подсюжет Python, используемый для отображения одной фигуры

Когда я использовал подзаголовок и пытался использовать следующий подзаговор для построения только одной фигуры, он выдавал ошибку:

AttributeError: 'AxesSubplot' object has no attribute 'flat'

fig, ax = plt.subplots(nrows=nrows, ncols=ncols,figsize=figsize)
for i, ax in enumerate(ax.flat):
    ax.plot(X, Y, color='k')

Как решить эту проблему, если я хочу произвольно установить количество подцифр? Как мне легко понять ax.flat?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
3 527
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

flat — это атрибут массивов numpy, который возвращает итератор. Например, если у вас есть такой двумерный массив:

import numpy as np
arr2d = np.arange(4).reshape(2, 2)
arr2d
# array([[0, 1],
#        [2, 3]])

атрибут flat предоставляется как удобный способ перебора этого массива, как если бы это был массив 1d:

for value in arr2d.flat:
    print(value)
# 0
# 1
# 2
# 3

Вы также можете сгладить массив с помощью метода flatten:

arr2d.flatten()
# array([0, 1, 2, 3])

Итак, возвращаясь к вашему вопросу, когда вы указываете:

  • ncols к 1 и nrows к значению больше 1 или наоборот, вы получаете оси в массиве 1d numpy, и в этом случае атрибут flat возвращает тот же массив.
  • как ncols, так и nrows до значений больше 1, вы получаете оси в массиве 2d, и в этом случае атрибут flat возвращает плоский массив.
  • оба ncols и nrows равны 1, вы получаете объект осей, у которого нет атрибута flat.

Таким образом, возможным решением было бы каждый раз превращать ваш объект ax в массив numpy:

fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize)

ax = np.array(ax)
for i, axi in enumerate(ax.flat):
    axi.plot(...)

Когда вы создаете набор подграфиков с несколькими строками/столбцами с помощью команды fig,ax=plt.subplots(), он возвращает fig и список осей ax. Форма списка ax имеет 2 измерения (строки, столбцы). Вот почему вам нужно сгладить его, чтобы он стал 1 измерением, когда вы повторяете список ax. Чтобы получить доступ к определенным осям, вам нужны индексы строк/столбцов, например, ax[r][c] — это оси в (r+1)-й строке/(c+1)-м столбце. Индексы отсчитываются от нуля. Рабочий код ниже демонстрирует, как это сделать.

import matplotlib.pyplot as plt
import numpy as np

nrows,ncols = 3,2
figsize = [5,9]
X = np.random.rand(6)
Y = np.random.rand(6)

fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize)
for i, axi in enumerate(ax.flat):
    axi.plot(X, Y, color='k')
    rowid = i // ncols
    colid = i % ncols
    axi.set_title("row:"+str(rowid)+",col:"+str(colid))

# You can access the axes by row_id, col_id.
# Now let's plot on ax[row_id][col_id] of your choice
ax[0][1].plot(Y,X,color='red')    # plot 2nd line in red
ax[2][0].plot(Y,X,color='green')  # plot 2nd line in green

plt.tight_layout(True)
plt.show()

Выходной график:

Вы можете использовать либо ax.ravel(), либо ax.flatten(). Ниже приведен простой пример

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(8, 6))

# for i, ax in enumerate(ax.flatten()):
for i, ax in enumerate(ax.ravel()):
    ax.plot([1,2,3], color='k')
plt.show()

Есть ровно один случай, когда код

fig, ax = plt.subplots(nrows=nrows, ncols=ncols,figsize=figsize)
for i, ax in enumerate(ax.flat):
    ax.plot(X, Y, color='k')

не будет работать, как ожидалось. Это для nrows = ncols = 1. Это связано с тем, что для одной строки и столбца ax является одним подзаголовком, а не массивом из нескольких подзаголовков.

Чтобы обойти эту проблему и иметь возможность использовать один и тот же код, не зная заранее nrows и ncols, используйте параметр squeeze=False. Это гарантирует, что ax всегда будет массивом и, следовательно, будет иметь атрибут .flat. Для лучшего понимания не называйте массив осей тем же именем, что и сами оси.

fig, axs = plt.subplots(nrows=nrows, ncols=ncols, squeeze=False, figsize=figsize)
for i, ax in enumerate(axs.flat):
    ax.plot(X, Y, color='k')

Другие вопросы по теме