【问题标题】:APLpy incompatibility with matplotlib gridspecAPLpy 与 matplotlib gridspec 不兼容
【发布时间】:2013-05-24 12:28:26
【问题描述】:

我基本上只是想结合gridspec 和APLpy。

但不知何故,一排子图中的第一个情节总是表现出来,这意味着它的大小不是它应该的大小。第一个图像显示了一个相当大的框架,而其他图像则非常适合二次方。

我基本上已经尝试了我能想到的一切来重新缩放或调整第一个图的大小:

  • 在使用 APLpy 填充之前和之后使用 transformsBbox 手动设置大小
  • 不要求 get_position().bounds,而只是在 APLpy 命令中要求 get_position()
  • 在填充子图前后使用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') 

有趣... 像 nordev 建议的那样,使用 for 循环会导致所有 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') 

【问题讨论】:

  • 变量img0img1img2img3分配了什么?代表图像路径的字符串?附带说明;使用循环而不是显式键入所有内容四次更不容易出错,而且更 Pythonic。
  • 是的,img0、img1、img2 和 img3 是代表图像路径的字符串。显然,使用 for 循环会更好看 ;) 很抱歉。
  • 尝试使用ax.set_aspect('equal', adjustable='box-forced')。如果涉及共享轴,这可能会有所帮助。
  • @tcaswell 不幸的是,这并没有改变任何事情。
  • 你解决过这个问题吗?

标签: python image matplotlib fits


【解决方案1】:

代码的第一个问题是行

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

创建一个新的轴对象,您可以独立于 FITSFigure 对象使用的轴进行操作。如果要修改轴,可以使用未记录的 fig._ax1 对象而不是 ax 对象。 YMMV,但一些 matplotlib 的 API 被(或冻结)aplpy 忽略;这有望随着转换为使用WCSAxes而改变。

您创建的 ax 对象的唯一好处是它们为您提供了可以传递给FITSFigure() 的位置。或者,我提交了pull request 以允许 GridSpec 直接与 subplot= 参数一起使用。

我认为您的问题可能与子图的默认位置不对称有关 - 请参阅 rcParams 中的 figure.subplot.leftfigure.subplot.right。试试:

gs=gridspec.GridSpec(1, 4, left=0.1, right=0.9)

【讨论】:

    猜你喜欢
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    相关资源
    最近更新 更多