Странность подзаголовка matplotlib

#python #matplotlib #subplot

Вопрос:

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

 import matplotlib.pylab as plt
import numpy

# Sample data
x = numpy.linspace(0, 2 * numpy.pi, 400)
y1 = numpy.sin(x ** 2)
y2 = numpy.cos(x ** 2)

figure, axes = plt.subplots(1, 2)
axes[0, 0].plot(x, y)
axes[0, 1].plot(x, y)
 

К сожалению, я получаю следующее сообщение об ошибке.

 ---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-4-124cb6e8d977> in <module>
      8 
      9 figure, axes = plt.subplots(1, 2)
---> 10 axes[0, 0].plot(x, y)
     11 axes[0, 1].plot(x, y)

IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed
 

Кроме того, если я запущу axes.shape , я получу вывод как (2,) . Я бы ожидал, что так оно и будет (1, 2) . Чего мне не хватает?

[Обратите внимание, что предыдущий-это минимальный рабочий пример, который в моем коде рассматривается как особый случай. Я не хочу проходить (ax1, ax2) маршрут в предыдущем примере, потому что я точно не знаю, сколько подзаголовков мне нужно заранее, поэтому я должен сделать это программно.

В частности, у меня есть функции $ n $, и я хочу построить графики формы $ (ceil(n / 2), 2) $. Поэтому я бы использовал, где находится моя итерационная переменная. axes[i // 2, i % 2] i Но когда $ n = 2 $, мой код ломается.]

Заранее спасибо!

[Правка: добавлен контекст, чтобы ответить на комментарий Тима.]

Комментарии:

1. Но ваш код отличается от примера. Это составляло массив 2×2. Ты делаешь 1х2. Вам просто нужно axes[0] и axes[1] .

2. @TimRoberts : Я обновил вопрос, чтобы добавить контекст. Я вижу это axes[0] и axes[1] это работает, но если я настрою 2D-сетку, она не должна вести себя как 1D, даже если есть только одно измерение, по которому мы движемся, нет?

3. «Должен» на самом деле не имеет значения. Я бы назвал это причудой. Это то, что есть, и вам нужно работать над этим. Вы всегда можете reshape это сделать; я думаю, что это массив numpy.

Ответ №1:

В соответствии с документацией matplotlib для plt.subplots :

  • если построен только один подзаголовок (nrows=ncols=1), результирующий объект с одной осью возвращается в виде скаляра.
  • для подзаголовков Nx1 или 1xM возвращаемый объект представляет собой массив объектов 1D numpy, состоящий из объектов Axes.
  • для NxM подзаголовки с N>1 и M>>1 возвращаются в виде 2D-массива.

Это поведение по умолчанию, и его можно изменить, установив squeeze аргумент в False ( plt.subplots(1, 2, squeeze = False) в вашем случае), и в этом случае он всегда будет возвращать 2D-массив:

возвращаемый объект Axes всегда представляет собой 2D-массив, содержащий экземпляры Axes, даже если он в конечном итоге равен 1×1.