You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建带Mollweide投影的放大内嵌子图?

解决Mollweide投影主图+内嵌图的天图绘制问题

问题概述

需要制作主坐标轴与内嵌坐标轴均采用Mollweide投影的天图,主图绘制已实现,但内嵌图存在以下问题:

  • 使用ligo.skymap示例代码时,轮廓不显示且x轴反向
  • 直接创建Mollweide投影内嵌图,无法设置轴范围聚焦目标天区
  • 使用普通内嵌图会导致轮廓变形,不符合物理需求

现有代码

主图代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

xmin = min(l)
xmax = max(l)
ymin = min(b)
ymax = max(b)
X, Y = np.meshgrid(np.linspace(xmin, xmax, 100), np.linspace(ymin, ymax, 100))

mpl.rcParams["text.usetex"] = True
fig = plt.figure(1)
fig.set_figheight(8)
fig.set_figwidth(8)

ax = plt.axes(projection='mollweide')
ax.grid()
# skypost为天区位置概率密度数据
plt.contour(X, Y, skypost, colors='blue', levels=[5, 50, 95])

尝试过的内嵌图代码

axesinset = plt.axes(
    [0.0, 0.2, 0.25, 0.25], 
    projection='astro degrees zoom', 
    center='110d +20d', 
    radius='10 deg' )
plt.sca(axesinset)
axesinset.contour(X, Y, skypost, colors='blue', levels=[5, 50, 95])
axesinset.grid()

可行解决方案

核心思路:直接创建Mollweide投影的内嵌轴,将所有坐标转换为弧度(符合Mollweide投影的要求),手动设置轴范围聚焦目标天区。

完整代码示例

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

# 加载经纬度数据l、b和天区概率密度数据skypost(此处省略加载逻辑)
xmin = min(l)
xmax = max(l)
ymin = min(b)
ymax = max(b)
X, Y = np.meshgrid(np.linspace(xmin, xmax, 100), np.linspace(ymin, ymax, 100))

# 主图绘制
mpl.rcParams["text.usetex"] = True
fig = plt.figure(1)
fig.set_figheight(8)
fig.set_figwidth(8)

ax = plt.axes(projection='mollweide')
ax.grid()
# 转换为弧度后绘制主图轮廓(Mollweide投影要求输入弧度)
ax.contour(np.radians(X), np.radians(Y), skypost, colors='blue', levels=[5, 50, 95])

# 内嵌图绘制
# 1. 创建Mollweide投影的内嵌轴,参数为[左, 下, 宽, 高](归一化坐标)
axesinset = plt.axes([0.0, 0.2, 0.25, 0.25], projection='mollweide')
axesinset.grid()

# 2. 定义目标天区的中心和半径(转换为弧度)
center_l = 110  # 目标中心经度(度)
center_b = 20   # 目标中心纬度(度)
radius = 10     # 天区半径(度)
center_l_rad = np.radians(center_l)
center_b_rad = np.radians(center_b)
radius_rad = np.radians(radius)

# 3. 设置内嵌轴的显示范围,聚焦目标天区
axesinset.set_xlim(center_l_rad - radius_rad, center_l_rad + radius_rad)
axesinset.set_ylim(center_b_rad - radius_rad, center_b_rad + radius_rad)

# 4. 绘制内嵌图轮廓,同样转换为弧度
axesinset.contour(np.radians(X), np.radians(Y), skypost, colors='blue', levels=[5, 50, 95])

# 可选:调整内嵌轴刻度大小,避免重叠
axesinset.tick_params(labelsize=8)

plt.show()

关键说明

  1. 坐标单位转换:matplotlib的Mollweide投影要求输入坐标为弧度而非角度,所有经纬度数据(包括网格和轴范围)都需要用np.radians()转换,这是之前轮廓不显示的核心原因。
  2. 内嵌轴范围设置:直接使用set_xlim()和set_ylim()传入弧度范围,即可实现目标天区的聚焦,无需依赖第三方投影。
  3. 避免投影冲突:放弃astro degrees zoom投影,改用原生Mollweide投影,确保内嵌图与主图投影一致,避免轮廓变形和轴反向问题。

内容的提问来源于stack exchange,提问作者Not Sure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 05:54:09