Оси из plt.subplots () являются объектом numpy.ndarray и не имеют графика атрибутов

Приведенная ниже информация может быть излишней, если вы пытаетесь понять сообщение об ошибке. Начните с чтения ответа от @ user707650.

Используя MatPlotLib, мне нужен был универсальный сценарий, который на основе моих данных создавал бы следующее.

Окно, содержащее подзаголовки a, расположенные таким образом, чтобы на столбец приходилось b подзаголовков. Я хочу иметь возможность изменять значения a и b.

Если у меня есть данные для подзаголовков 2a, мне нужно 2 окна, каждое с ранее описанными подзаголовками "a, расположенными в соответствии с b частями на столбец ".

Данные x и y, которые я рисую, представляют собой числа с плавающей запятой, хранящиеся в np.arrays и структурированы следующим образом:

  • Данные x всегда одинаковы для всех графиков и имеют длину 5.

     'x_vector': [0.000, 0.005, 0.010, 0.020, 0.030, 0.040]
    
  • Данные y всех графиков хранятся в y_vector, где данные для первого графика хранятся с индексами от 0 до 5. Данные для второго графика хранятся с индексами с 6 по 11. Третий график получает 12-18, четвертый 19-24 и так далее.

Всего для этого набора данных у меня есть 91 график (т.е. 91 * 6 = 546 значений, хранящихся в y_vector).

Попытка:

import matplotlib.pyplot as plt

# Options:
plots_tot = 14 # Total number of plots. In reality there is going to be 7*13 = 91 plots.
location_of_ydata = 6 # The values for the n:th plot can be found in the y_vector at index 'n*6' through 'n*6 + 6'.
plots_window = 7 # Total number of plots per window.
rows = 2 # Number of rows, i.e. number of subplots per column.

# Calculating number of columns:
prim_cols = plots_window / rows
extra_cols = 0
if plots_window % rows > 0:
    extra_cols = 1
cols = prim_cols + extra_cols

print 'cols:', cols
print 'rows:', rows

# Plotting:
n=0
x=0
fig, ax = plt.subplots(rows, cols)
while x <= plots_tot:
    ax[x].plot(x_vector, y_vector[n:(n+location_of_ydata)], 'ro')
    if x % plots_window == plots_window - 1:
        plt.show() # New window for every 7 plots.
    n = n+location_of_ydata
    x = x+1

Я получаю следующую ошибку:

cols: 4
rows: 2
Traceback (most recent call last):
  File "Script.py", line 222, in <module>
    ax[x].plot(x_vector, y_vector[n:(n+location_of_ydata)], 'ro')
AttributeError: 'numpy.ndarray' object has no attribute 'plot'

person Lucubrator    schedule 22.06.2016    source источник
comment
Импорт numpy не имеет значения: matplotlib (pyplot) уже делает это за кулисами, поскольку это основная зависимость matplotlib.   -  person    schedule 22.06.2016


Ответы (4)


Если вы отлаживаете свою программу, просто печатая ax, вы быстро обнаружите, что ax - это двумерный массив: одно измерение для строк, другое для столбцов.

Таким образом, вам нужны два индекса для индексации ax, чтобы получить фактический экземпляр AxesSubplot, например:

ax[1,1].plot(...)

Если вы хотите перебирать подзаголовки так, как вы это делаете сейчас, сначала сглаживая ax:

ax = ax.flatten()

и теперь ax - это одномерный массив. Я не знаю, проходят ли сначала строки или столбцы, но если что-то не так, используйте транспонирование:

ax = ax.T.flatten()

Конечно, теперь имеет больше смысла просто создавать каждый подзаголовок на лету, потому что у него уже есть индекс, а два других числа фиксированы:

for x < plots_tot:
     ax = plt.subplot(nrows, ncols, x+1)

Примечание: у вас есть x <= plots_tot, но если x начинается с 0, вы получите IndexError рядом с вашим текущим кодом (после выравнивания массива). Matplotlib (к сожалению) 1-индексирован для подзаголовков. Я предпочитаю использовать переменную с индексом 0 (стиль Python) и просто добавляю +1 для индекса подзаголовка (как указано выше).

person Community    schedule 22.06.2016

Проблема здесь в том, как matplotlib обрабатывает подзаголовки. Просто сделайте следующее:

fig, axes = plt.subplots(nrows=1, ncols=2)
for axis in axes:
    print(type(axis))

вы получите объект matplotlib, который на самом деле представляет собой одномерный массив, по которому можно перемещаться с использованием одного индекса, то есть оси [0], оси [1] ... и так далее. Но если вы это сделаете

fig, axes = plt.subplots(nrows=2, ncols=2)
for axis in axes:
    print(type(axis))

вы получите numpy ndarray объект, который на самом деле представляет собой двумерный массив, по которому можно перемещаться только с использованием двух индексов, то есть оси [0, 0], оси [1, 0] ... и так далее. Так что помните, как вы включаете цикл for для обхода объекта осей.

person bluedroid    schedule 23.11.2019

В случае, если вы используете графики N на 1, например, если вам нравится fig, ax = plt.subplots(3, 1), тогда, пожалуйста, сделайте likeax[plot_count].plot(...)

person Cloud Cho    schedule 16.08.2019

Оси находятся в 2-м, а не в 1-м, поэтому вы не можете выполнять итерацию с использованием одного цикла. Вам понадобится еще один цикл:

 fig,axes=plt.subplots(nrows=2,ncols=2)
    plt.tight_layout()
    for ho in axes:
        for i in ho:
            i.plot(a,a**2)

Это не проблема, но если я попробую:

for i in axes:
      i.plot(a,a**2)

возникает ошибка.

person Devansh Chowdhury    schedule 20.04.2020