Создание квадратных подсетей (одинаковой высоты и ширины) в matplotlib

Когда я запускаю этот код

from pylab import *

figure()
ax1 = subplot(121)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

Я получаю две подзаголовки, которые "хлюпаются" в X-размерности. Как получить эти подзаговоры так, чтобы высота оси Y была равна ширине оси X для обеих подзадач?

Я использую matplotlib v.0.99.1.2 на Ubuntu 10.04.

Обновление 2010-07-08. Посмотрите на некоторые вещи, которые не работают.

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

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

matplotlib настаивает на автоматическом масштабировании.

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

В этом случае данные полностью исчезают. WTF, matplotlib? Просто WTF?

Хорошо, возможно, если мы зафиксируем соотношение сторон?

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
axes().set_aspect('equal')
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

Это приводит к тому, что первый подзаговор полностью исчезает. Это весело! Кто придумал этот?

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

Ответы

Ответ 1

Ваша проблема при настройке аспекта графиков появляется, когда вы используете sharex и sharey.

Один способ обхода заключается в том, чтобы просто не использовать общие оси. Например, вы можете сделать это:

from pylab import *

figure()
subplot(121, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
show()

Тем не менее, лучшим решением является изменение "регулируемого" ключа... Вы хотите регулировать = "поле", но когда вы используете общие оси, он должен быть регулируемым = "datalim" (и устанавливать его обратно to 'box' дает ошибку).

Однако для adjustable существует третий вариант для adjustable: adjustable="box-forced".

Например:

from pylab import *

figure()
ax1 = subplot(121, aspect='equal', adjustable='box-forced')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal', adjustable='box-forced', sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
show()

Или в более современном стиле (обратите внимание: эта часть ответа не сработала бы в 2010 году):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=2, sharex=True, sharey=True)
for ax in axes:
    ax.plot([1, 2, 3], [1, 2, 3])
    ax.set(adjustable='box-forced', aspect='equal')

plt.show()

В любом случае вы получите что-то похожее на:

введите описание изображения здесь

Ответ 2

Попробуйте:

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3])
plot([1, 2, 3], [1, 2, 3])
##axes().set_aspect('equal')
ax2 = subplot(122, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3])
plot([1, 2, 3], [1, 2, 3])
draw()
show()

Я прокомментировал строку axes(), так как это создало бы новый axes в произвольном месте, а не готовый subplot с вычисленной позицией.

Вызов subplot фактически создает экземпляр axes, что означает, что он может использовать те же свойства, что и для axes.

Надеюсь, это поможет:)