Matplotlib 颜色条和 WCS 投影
Matplotlib colorbar and WCS projection
我正在尝试编写一个函数来显示顶部带有颜色条的天文图像(自动与 x 轴的长度相同)。
我遇到了问题,因为当我尝试将刻度线放在顶部时,它什么也没做……它使刻度线保持在颜色条的底部(以及颜色条的 y 轴上的刻度线)。
我认为这可能是 x 轴的 WCS 坐标有问题,因为当我尝试在没有投影的情况下执行此操作时效果很好!
import numpy as np
import matplotlib.pyplot as plt
from astropy import wcs
from matplotlib.colors import PowerNorm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib import cm
#WCS coordinate system
w = wcs.WCS(naxis=2)
w.wcs.crpix = [23.5, 23.5]
w.wcs.cdelt = np.array([-0.0035, 0.0035])
w.wcs.crval = [266.8451, -28.151658]
w.wcs.ctype = ["RA---TAN", "DEC--TAN"]
w.wcs.set_pv([(2, 1, 45.0)])
#generate an array as image test
data = (np.arange(10000).reshape((100,100)))
#display image
fig = plt.figure()
ax = plt.gca(projection=w)
graf = ax.imshow(data, origin='lower', cmap=cm.viridis, norm=PowerNorm(1))
#colorbar
divider = make_axes_locatable(ax)
cax = divider.append_axes("top", size="5%")
cbar = fig.colorbar(graf, cax=cax, orientation='horizontal')
cax.xaxis.set_ticks_position('top')
fig.show()
谢谢!
您需要使用 WCSAxes
的内部机制来处理 WCS 投影中的刻度。看起来 WCSAxes
通过坐标地图容器(您可以在 cbar.ax.coords
中找到它)而不是 xaxis/yaxis 属性(似乎用得不多)来处理颜色条刻度。
因此,在 运行 你的代码之后,以下技巧对我有用并且 xticks 向上移动:
c_x = cbar.ax.coords['x']
c_x.set_ticklabel_position('t')
cbar.update_normal(cax)
您可以使用 matplotlib 的 axes class 解决此问题。
...
import matplotlib.axes as maxes
cax = divider.append_axes("top", size="5%", axes_class=maxes.Axes)
...
为了让这样的东西起作用,我需要一些额外的参数:
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cax.coords[0].grid(False)
cax.coords[1].grid(False)
cax.tick_params(direction='in')
cax.coords[0].set_ticks(alpha=0, color='w', size=0, values=[]*u.dimensionless_unscaled)
cax.coords[1].set_ticklabel_position('r')
cax.coords[1].set_axislabel_position('r')
因为默认轴打开了网格,标签在左侧,并且启用了 x 轴标签。我不确定为什么原来的 post 没有问题。
我正在尝试编写一个函数来显示顶部带有颜色条的天文图像(自动与 x 轴的长度相同)。 我遇到了问题,因为当我尝试将刻度线放在顶部时,它什么也没做……它使刻度线保持在颜色条的底部(以及颜色条的 y 轴上的刻度线)。 我认为这可能是 x 轴的 WCS 坐标有问题,因为当我尝试在没有投影的情况下执行此操作时效果很好!
import numpy as np
import matplotlib.pyplot as plt
from astropy import wcs
from matplotlib.colors import PowerNorm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib import cm
#WCS coordinate system
w = wcs.WCS(naxis=2)
w.wcs.crpix = [23.5, 23.5]
w.wcs.cdelt = np.array([-0.0035, 0.0035])
w.wcs.crval = [266.8451, -28.151658]
w.wcs.ctype = ["RA---TAN", "DEC--TAN"]
w.wcs.set_pv([(2, 1, 45.0)])
#generate an array as image test
data = (np.arange(10000).reshape((100,100)))
#display image
fig = plt.figure()
ax = plt.gca(projection=w)
graf = ax.imshow(data, origin='lower', cmap=cm.viridis, norm=PowerNorm(1))
#colorbar
divider = make_axes_locatable(ax)
cax = divider.append_axes("top", size="5%")
cbar = fig.colorbar(graf, cax=cax, orientation='horizontal')
cax.xaxis.set_ticks_position('top')
fig.show()
谢谢!
您需要使用 WCSAxes
的内部机制来处理 WCS 投影中的刻度。看起来 WCSAxes
通过坐标地图容器(您可以在 cbar.ax.coords
中找到它)而不是 xaxis/yaxis 属性(似乎用得不多)来处理颜色条刻度。
因此,在 运行 你的代码之后,以下技巧对我有用并且 xticks 向上移动:
c_x = cbar.ax.coords['x']
c_x.set_ticklabel_position('t')
cbar.update_normal(cax)
您可以使用 matplotlib 的 axes class 解决此问题。
...
import matplotlib.axes as maxes
cax = divider.append_axes("top", size="5%", axes_class=maxes.Axes)
...
为了让这样的东西起作用,我需要一些额外的参数:
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cax.coords[0].grid(False)
cax.coords[1].grid(False)
cax.tick_params(direction='in')
cax.coords[0].set_ticks(alpha=0, color='w', size=0, values=[]*u.dimensionless_unscaled)
cax.coords[1].set_ticklabel_position('r')
cax.coords[1].set_axislabel_position('r')
因为默认轴打开了网格,标签在左侧,并且启用了 x 轴标签。我不确定为什么原来的 post 没有问题。