「跟著黑蛋用Streamlit速成天文資料分析Web App」系列文[7]:初版一刷系外行星資料表篩選器app

黑蛋收到一則從Asana專案管理軟體傳來的任務通知,標題為:「研究能快速篩選系外行星資料表的方法」,PM貳婰舞在任務描述區塊中貼了一個錄影連結,他在影片中說明:「雖然我們現在能藉由程式取得並匯出系外行星資料表,但客戶時常會有資料篩選的需求,例如,他有時只要某年份區間內被發現的行星,或是只要被某個方法發現的行星,或是要去除某幾個欄位值為空值的行星,所以需要請你研究能快速篩選系外行星資料表的方法。」

黑蛋心想,雖然能用Google Sheets等工具過濾由程式產生的系外行星資料表,但若能將資料取得、篩選、匯出等功能都集中在同一地方或許比較方便,所以,他想試試Streamlit能否做到。

首先,他開啟一個命名為exoplanet_table_filter.py的Python script,將前幾天研究Astroquery套件時寫好的函式get_exoplanet_table_by_astroquery()擺了進去,加上頁面標題及app簡介後,呼叫該函式並呈現系外行星資料表。不過,他發現在資料表載入時會等待一段時間,為了讓使用者體驗好一些,他使用st.spinner元件來呈現「正在載入系外行星資料表,請稍候...」的訊息。

# exoplanet_table_filter.py
import streamlit as st
from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive

def get_exoplanet_table_by_astroquery():
    table_name = 'pscomppars'
    columns = 'pl_name,hostname,sy_dist,pl_orbper,pl_bmasse,pl_rade,disc_year,discoverymethod'
    exoplanet_table = NasaExoplanetArchive.query_criteria(
        table=table_name, select=columns
    )
    exoplanet_table = exoplanet_table.to_pandas()
    exoplanet_table = exoplanet_table.rename(
        columns={
            'pl_name': '行星名稱',
            'hostname': '所屬恆星名稱',
            'sy_dist': '與地球的距離(單位:秒差距)',
            'pl_orbper': '行星軌道週期(單位:天)',
            'pl_bmasse': '行星質量(單位:地球質量)',
            'pl_rade': '行星半徑(單位:地球半徑)',
            'disc_year': '發現年份',
            'discoverymethod': '發現方法'
        }
    )
    exoplanet_table.sort_values(
        by='發現年份', ascending=False, inplace=True, ignore_index=True
    )

    return exoplanet_table


page_title = '系外行星資料表篩選器'
st.set_page_config(page_title=page_title, page_icon=':star', layout='wide')
st.title(page_title)
st.info('藉由[Astroquery](https://astroquery.readthedocs.io/en/latest/ipac/nexsci/nasa_exoplanet_archive.html)套件取得[NASA系外行星資料庫](https://exoplanetarchive.ipac.caltech.edu/)提供的資料表,篩選出所需資料後匯出CSV檔。')

with st.spinner('正在載入系外行星資料表,請稍候...'):
    exoplanet_table = get_exoplanet_table_by_astroquery()

st.dataframe(exoplanet_table)

接著,黑蛋找齊用來組裝篩選功能的元件:以st.select_slider篩選年份範圍、用st.selectbox篩選發現方法、用st.multiselect多選要去除空值的欄位,另外,他還用了st.sidebar以便將這些元件集中放在側邊欄。最後,他安置了st.download_button,讓使用者可以將篩選後的資料表匯出成CSV檔,這樣系外行星資料表篩選器app就完成啦!完整的程式碼如下:

# exoplanet_table_filter.py
import streamlit as st
from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive


def get_exoplanet_table_by_astroquery():
    table_name = 'pscomppars'
    columns = 'pl_name,hostname,sy_dist,pl_orbper,pl_bmasse,pl_rade,disc_year,discoverymethod'
    exoplanet_table = NasaExoplanetArchive.query_criteria(
        table=table_name, select=columns
    )
    exoplanet_table = exoplanet_table.to_pandas()
    exoplanet_table = exoplanet_table.rename(
        columns={
            'pl_name': '行星名稱',
            'hostname': '所屬恆星名稱',
            'sy_dist': '與地球的距離(單位:秒差距)',
            'pl_orbper': '行星軌道週期(單位:天)',
            'pl_bmasse': '行星質量(單位:地球質量)',
            'pl_rade': '行星半徑(單位:地球半徑)',
            'disc_year': '發現年份',
            'discoverymethod': '發現方法'
        }
    )
    exoplanet_table.sort_values(
        by='發現年份', ascending=False, inplace=True, ignore_index=True
    )

    return exoplanet_table


page_title = '系外行星資料表篩選器'
st.set_page_config(page_title=page_title, page_icon=':star', layout='wide')
st.title(page_title)
st.info('藉由[Astroquery](https://astroquery.readthedocs.io/en/latest/ipac/nexsci/nasa_exoplanet_archive.html)套件取得[NASA系外行星資料庫](https://exoplanetarchive.ipac.caltech.edu/)提供的資料表,篩選出所需資料後匯出CSV檔。')

with st.spinner('正在載入系外行星資料表,請稍候...'):
    exoplanet_table = get_exoplanet_table_by_astroquery()

year_min = int(exoplanet_table['發現年份'].min())
year_max = int(exoplanet_table['發現年份'].max())
year_lst = list(range(year_min, year_max + 1))
year_range = st.sidebar.select_slider(
    '篩選某年份區間內被發現的行星',
    options=year_lst,
    value=(year_min, year_max), 
)
exoplanet_table = exoplanet_table[
    (exoplanet_table['發現年份'] >= year_range[0]) &
    (exoplanet_table['發現年份'] <= year_range[1])
]

method_lst = sorted(list(exoplanet_table['發現方法'].unique()))
selected_method = st.sidebar.selectbox(
    '篩選被某個方法發現的行星', ['不限'] + method_lst
)
if selected_method != '不限':
    exoplanet_table = exoplanet_table[exoplanet_table['發現方法'] == selected_method]

column_name_lst = list(exoplanet_table.columns)
selected_columns = st.sidebar.multiselect(
    '去除某幾個欄位值為空值的行星', column_name_lst
)
exoplanet_table = exoplanet_table.dropna(subset=selected_columns)

exoplanet_table = exoplanet_table.reset_index(drop=True)
st.dataframe(exoplanet_table)
st.sidebar.download_button(
    label='將篩選資料表匯出成CSV檔',
    data=exoplanet_table.to_csv(index=False),
    file_name='exoplanet_table.csv',
    mime='text/csv'
)

此系列文由蘇羿豪撰寫,以「創用CC 姓名標示 4.0(CC BY 4.0)國際版授權條款」釋出。

Subscribe to 天文背包黑客
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.