Оси из plt.subplots() - объект numpy.ndarray и не имеет атрибута "plot"

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

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

Окно, содержащее вложенные участки, расположенные таким образом, чтобы в каждом столбце было 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'

Ответ 1

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

Ответ 2

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