Несовместимость APLpy со спецификацией сетки matplotlib

Я просто пытаюсь объединить gridspec и APLpy.

Но каким-то образом первый сюжет в ряду подсюжетов всегда разыгрывается, то есть его размер не такой, каким он должен быть. Первое изображение показывает довольно большую рамку, в то время как другие имеют квадратную форму.

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

  • Установка размера вручную с помощью transforms и Bbox до и после заполнения с помощью APLpy
  • Не запрашивать get_position().bounds, а просто get_position() в команде APLpy
  • используя set_aspect('equal') до и после заполнения подзаговора

Ничего не работает. Это также не имеет ничего общего с изображениями, построение разных изображений или изменение порядка приводит к тому же беспорядку.

Я просто не могу убедить первый сюжет изменить свой размер. Нет никакого способа обойти gridspec, так как эта серия подсюжетов является частью более крупного сюжета, и использование чего-либо, кроме gridspec, сделало бы все остальное довольно сложным.

Любая помощь будет принята с благодарностью, это сводит меня с ума.

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib import gridspec
import aplpy

f=plt.figure()
gs=gridspec.GridSpec(1,4)
ax0=plt.subplot(gs[0,0]);ax1=plt.subplot(gs[0,1]);ax2=plt.subplot(gs[0,2]);ax3=plt.subplot(gs[0,3])
ax0.set_aspect('equal'); ax1.set_aspect('equal'); ax2.set_aspect('equal'); ax3.set_aspect('equal');
ax0.axes.get_xaxis().set_ticks([]); ax1.axes.get_xaxis().set_ticks([]); ax2.axes.get_xaxis().set_ticks([]); ax3.axes.get_xaxis().set_ticks([])
ax0.axes.get_yaxis().set_ticks([]); ax1.axes.get_yaxis().set_ticks([]); ax2.axes.get_yaxis().set_ticks([]); ax3.axes.get_yaxis().set_ticks([])

fig0=aplpy.FITSFigure(img0, figure=f, subplot=ax0.get_position().bounds); fig0.show_grayscale(invert=True)
fig1=aplpy.FITSFigure(img1, figure=f, subplot=ax1.get_position().bounds); fig1.show_grayscale(invert=True)
fig2=aplpy.FITSFigure(img2, figure=f, subplot=ax2.get_position().bounds); fig2.show_grayscale(invert=True)
fig3=aplpy.FITSFigure(img3, figure=f, subplot=ax3.get_position().bounds); fig3.show_grayscale(invert=True)

fig0.axis_labels.hide_x(); fig0.axis_labels.hide_y(); fig0.tick_labels.hide_x(); fig0.tick_labels.hide_y()
fig1.axis_labels.hide_x(); fig1.axis_labels.hide_y(); fig1.tick_labels.hide_x(); fig1.tick_labels.hide_y()
fig2.axis_labels.hide_x(); fig2.axis_labels.hide_y(); fig2.tick_labels.hide_x(); fig2.tick_labels.hide_y()
fig3.axis_labels.hide_x(); fig3.axis_labels.hide_y(); fig3.tick_labels.hide_x(); fig3.tick_labels.hide_y()

f.savefig('test.png') 

Интересно... Использование цикла for, как предложил nordev, приводит к тому, что все 4 графика не являются квадратичными.

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib import gridspec
import aplpy

f=plt.figure()
gs=gridspec.GridSpec(1,4)
#img0,... are strings representing the image path
img_list=[img0, img1, img2, img3]

for i in range(0,4):
    ax=plt.subplot(gs[0,i])

    ax.set_aspect('equal')
    ax.axes.get_xaxis().set_ticks([]); ax.axes.get_yaxis().set_ticks([])

    fig=aplpy.FITSFigure(img_list[i], figure=f, subplot=ax.get_position())
    fig.show_grayscale(invert=True)

    fig.axis_labels.hide_x(); fig.axis_labels.hide_y()
    fig.tick_labels.hide_x(); fig.tick_labels.hide_y()

f.savefig('test.png') 

person Astro_Anna    schedule 24.05.2013    source источник
comment
Что присваивается переменным img0, img1, img2 и img3? Строка, представляющая путь к изображениям? На заметку; использование циклов for вместо явного ввода всего четыре раза менее подвержено ошибкам и более Pythonic.   -  person sodd    schedule 24.05.2013
comment
Да, img0, img1, img2 и img3 — это строки, представляющие путь к изображениям. Очевидно, что использование цикла for выглядело бы лучше ;) Извините за это.   -  person Astro_Anna    schedule 24.05.2013
comment
Попробуйте использовать ax.set_aspect('equal', adjustable='box-forced'). Это может помочь, если задействованы общие оси.   -  person tacaswell    schedule 24.05.2013
comment
@tcaswell К сожалению, это ничего не меняет.   -  person Astro_Anna    schedule 24.05.2013
comment
Вы когда-нибудь разбирались с этим?   -  person tacaswell    schedule 05.05.2014


Ответы (1)


Первая проблема с кодом — это строка

ax=plt.subplot(gs[0,i])

Это создает новый объект осей, которым вы управляете независимо от осей, используемых объектом FITSFigure. Если вы хотите изменить оси, вы можете использовать недокументированные объекты fig._ax1 вместо ваших объектов оси. YMMV, но некоторые из API matplotlib игнорируются (или зависают) aplpy; мы надеемся, что это изменится с переходом на использование WCSAxes.

Единственное хорошее использование объектов топора, которые вы создаете, заключается в том, что они дают вам позиции для перехода к FITSFigure(). В качестве альтернативы я отправил запрос на вытягивание, чтобы разрешить прямое использование GridSpec с параметром subplot= .

Я думаю, что ваша проблема может быть связана с несимметричным положением подзаголовков по умолчанию - см. figure.subplot.left и figure.subplot.right в rcParams. Пытаться:

gs=gridspec.GridSpec(1, 4, left=0.1, right=0.9)
person sargas    schedule 11.07.2014