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

如何用Plotly实现Aitoff投影天图叠加散点?转图报错求解

如何用Plotly实现Aitoff投影的天文散点图

问题背景

需要在仪表板中插入一张Aitoff投影的天图,叠加从数据库获取的散点数据,参考类似Matplotlib Aitoff投影和天文坐标散点的效果。尝试用Matplotlib生成图后转Plotly失败,使用px.scatter_geo也不符合需求,运行代码时报错:ValueError: 为'data'属性接收到无效元素。

之前的尝试代码:

@app.callback(
    Output('aitoff', 'children'),
    Input('my-table', 'data')
)
def add_row(data):
    df_grpah = pd.DataFrame(data)
    ra = coord.Angle(df_grpah["ra"], unit=u.hour) # 创建Angle对象
    ra = ra.wrap_at(180*u.degree)
    dec = coord.Angle(df_grpah['dec'],unit=u.deg)
    print("Ra: ", ra.degree)
    print("Dec: ", dec.degree)
    fig = plt.figure(figsize=(8,6))
    ax = fig.add_subplot(111, projection="aitoff")
    ax.scatter(ra.radian, dec.radian)
    ax.grid(True)
    figure = go.Figure(fig)
    return [
        html.Div(children=[dcc.Graph(figure=figure, className="card")])
    ]

用到的坐标数据:

Ra:  [  73.6305     56.868975  -81.49779   -28.375005  -52.832145  145.95
 -175.296    -151.65      101.85     -154.5      -175.821   ]
Dec:  [-72.5771    26.622     23.530393  38.21      89.348426  14.7899
 -28.042     30.27      25.28      17.76      -4.3204  ]

解决方案

1. 报错原因

你之前的代码报错是因为go.Figure()不能直接接收Matplotlib的fig对象作为参数,两者的图形结构完全不同,无法直接转换。

2. 用Plotly直接实现Aitoff投影散点图

Plotly本身没有内置Aitoff投影,但可以通过手动转换坐标模拟实现,步骤如下:

步骤1:坐标转换(和Matplotlib逻辑一致)

先将RA(赤经)转换为弧度并做180度环绕处理,Dec(赤纬)直接转弧度。注意需要反转RA的方向,因为Aitoff投影中RA从右到左递增,和常规笛卡尔轴方向相反。

步骤2:用Plotly散点图模拟Aitoff投影

使用go.Scatter绘制转换后的坐标,自定义网格和轴标签匹配Aitoff样式。

完整代码示例:

import plotly.graph_objects as go
import pandas as pd
from astropy import coord, units as u

@app.callback(
    Output('aitoff', 'children'),
    Input('my-table', 'data')
)
def add_row(data):
    df_graph = pd.DataFrame(data)
    # 处理坐标:和Matplotlib一致的转换逻辑
    ra = coord.Angle(df_graph["ra"], unit=u.hour)
    ra = ra.wrap_at(180*u.degree)
    dec = coord.Angle(df_graph['dec'], unit=u.deg)
    
    # 转换为弧度,反转RA方向匹配Aitoff投影布局
    ra_rad = -ra.radian
    dec_rad = dec.radian
    
    # 创建Plotly图形
    fig = go.Figure()
    
    # 添加散点数据
    fig.add_trace(go.Scatter(
        x=ra_rad,
        y=dec_rad,
        mode='markers',
        marker=dict(size=8, color='darkblue')
    ))
    
    # 自定义布局,模拟Aitoff投影样式
    fig.update_layout(
        width=800,
        height=600,
        xaxis=dict(
            title='赤经 (RA)',
            tickmode='array',
            tickvals=[-3.14, -1.57, 0, 1.57, 3.14],
            ticktext=['180°', '90°', '0°', '270°', '180°'],
            gridcolor='lightgray',
            gridwidth=1
        ),
        yaxis=dict(
            title='赤纬 (Dec)',
            tickmode='array',
            tickvals=[-1.57, -0.785, 0, 0.785, 1.57],
            ticktext=['-90°', '-45°', '0°', '45°', '90°'],
            gridcolor='lightgray',
            gridwidth=1
        ),
        title='Aitoff投影天文散点图',
        plot_bgcolor='white'
    )
    
    return [
        html.Div(children=[dcc.Graph(figure=fig, className="card")])
    ]

3. 补充说明

  • 可以结合astropy的坐标转换工具,确保天文坐标处理的准确性。
  • Plotly的scatter_geo主要面向地理坐标,无法直接支持天文Aitoff投影,手动转换坐标是更可行的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:35:42