NASA(nasapy)のpythonライブラリを使ってみた

Pythonのnasapyライブラリを使ってみた

***

# NASAのAPIキーを取得する

1.  NASAのAPIキー取得ページ <https://api.nasa.gov/> にアクセスします。

2.  「Generate API Key」ボタンをクリックします。

3.  必要な情報（名前、メールアドレスなど）を入力し、「Sign Up」ボタンをクリックします。

4.  登録したメールアドレスにAPIキーが送られてきます。そのキーをコピーして、Pythonのコード内で使用します。

以上がNASAのAPIキーを取得する手順です。このキーを使うことで、NASAのAPIにより多くのリクエストを送ることができます。

***

# NASAの画像データ

```python
!pip install nasapy

from nasapy import Nasa

nasa = Nasa(key='API key')

picture = nasa.picture_of_the_day()
print(picture)
```

結果、以下のような情報が出てきます

この出力は、NASAのAstronomy Picture of the Day (APOD) APIから取得した情報を示しています。以下に各フィールドの説明を記載します：

*   'copyright': 画像の著作権者（この場合は'Mike Wenz'）。
*   'date': 画像が公開された日付（'2023-08-01'）。
*   'explanation': 画像についての詳細な説明。この場合、太陽のプロミネンス（ガスの塊）について説明しています。
*   'hdurl': 高解像度の画像へのURL。
*   'media_type': メディアの種類（この場合は'image'）。
*   'service_version': 使用したAPIのバージョン（'v1'）。
*   'title': 画像のタイトル（'Monster Solar Prominence'）。
*   'url': 画像へのURL。

この情報を用いて、NASAのAPODから取得した画像を表示したり、画像についての詳細な情報を提供したりすることができます。

## NASAの画像データを表示する

それを表示します

```python
from PIL import Image
import requests
from io import BytesIO
import matplotlib.pyplot as plt

response = requests.get(picture['url'])
img = Image.open(BytesIO(response.content))

plt.imshow(img)
plt.show()
```

![](https://pbs.twimg.com/media/F2hphRta8AA3iVK?format=png\&name=small)

表示された画像は、「Monster Solar Prominence（モンスター太陽プロミネンス）」と題されたもので、太陽の表面近くに存在する巨大なガスの柱（太陽プロミネンス）を描いています。この画像は、アリゾナ州ギルバートで小型望遠鏡によって撮影されました。

太陽プロミネンスは、太陽の表面から数万キロもの高さに突き出たガスの塊で、太陽の磁場によって支えられています。通常、プロミネンスはゆっくりと形を変えながら約1ヶ月で太陽に戻ります。しかし、時折、突如として爆発し、太陽系にエネルギー豊富な粒子を放出します。これらの粒子は地球に到達することもあります。

この画像は、太陽が活発な状態にあることを示しています。特に、プロミネンス、フィラメント（太陽の表面に見られる暗い線状の構造）、太陽黒点、大規模な活動領域などが多く観測されています。これは、2025年に向けて太陽活動の最大期（太陽極大期）が近づいていることを示しています。

***

# 火星の天気データ

```python
# 火星の天気データ：火星探査車が送信する天気データにアクセスできます。
weather = nasa.mars_weather()
print(weather)

```

結果

取得したデータは火星の天気データですが、具体的な天気情報（気温、風速、気圧など）は含まれていません。`'sol_keys': []`となっている部分が、具体的な天気情報が記録される場所ですが、現在は空（\[]）となっています。

また、`'validity_checks'`の部分は、データの妥当性チェックに関する情報を示しています。この例では、火星の1219番目のソル（火星の1日）のデータについて、6時間から12時間のデータが存在するものの、そのデータは無効（'valid': False）であると示されています。

このような結果が返ってきた理由としては、データの更新タイミングや、火星探査車からのデータ送信の問題などが考えられます。再度同じコードを実行するか、別の日付を指定してデータを取得してみてください。

***

# 近づいている小惑星のデータ

```python
# 近づいている小惑星のデータ：近くを通過する小惑星のデータにアクセスできます。
import requests
import json

response = requests.get('https://api.nasa.gov/neo/rest/v1/feed?start_date=2023-07-01&end_date=2023-07-07&api_key='API key')
asteroids = json.loads(response.text)

print(asteroids)

# Print the name and close approach date of each asteroid
for date in asteroids['near_earth_objects']:
    for asteroid in asteroids['near_earth_objects'][date]:
        print('Name:', asteroid['name'])
        print('Close Approach Date:', asteroid['close_approach_data'][0]['close_approach_date'])
        print('---')


```

表示されたデータは、2023年7月1日から2023年7月7日までの間に地球に接近する予定の小惑星のリストです。各小惑星の名前と、地球に最も接近する日（Close Approach Date）が表示されています。

この情報は、小惑星が地球にどれだけ近づくか、また、その小惑星が地球に衝突する可能性があるかどうかを評価するために使用されます。NASAはこれらのデータを用いて、地球に衝突する可能性のある小惑星を追跡し、その軌道を計算しています。

なお、ここで表示されている小惑星が地球に衝突する可能性があるというわけではありません。これらの小惑星は地球に「接近」するだけで、その多くは地球から数百万キロ以上離れた場所を通過します。

## グラフ化

```python
import pandas as pd
import matplotlib.pyplot as plt

# Convert the asteroid data to a pandas DataFrame
data = []
for date in asteroids['near_earth_objects']:
    for asteroid in asteroids['near_earth_objects'][date]:
        data.append([asteroid['name'], asteroid['close_approach_data'][0]['close_approach_date']])
df = pd.DataFrame(data, columns=['Name', 'Close Approach Date'])

# Convert the 'Close Approach Date' column to datetime
df['Close Approach Date'] = pd.to_datetime(df['Close Approach Date'], format='%Y-%m-%d').dt.date

# Count the number of asteroids per date
counts = df['Close Approach Date'].value_counts().sort_index()

# Plot the number of asteroids per date
counts.plot(kind='bar')
plt.xlabel('Date')
plt.ylabel('Number of Asteroids')
plt.title('Number of Asteroids Approaching Earth')
plt.show()

```

![](https://pbs.twimg.com/media/F2hqpE_aAAYIaZN?format=png\&name=small)

Pythonのライブラリであるpandasとmatplotlibを使うと、取得した小惑星のデータを表やグラフで視覚的に表示することができます。

取得した小惑星のデータをpandasのデータフレームに変換し、そのデータフレームを使って小惑星の最接近日ごとの数を棒グラフで表示するコードを示します。

***

# DONKI API

```python
import requests
import json

response = requests.get('https://api.nasa.gov/DONKI/FLR?startDate=2023-07-01&endDate=2023-07-31&api_key='API key')
solar_flare = json.loads(response.text)

print(solar_flare)

```

これはNASAのDONKI（Space Weather Database Of Notifications, Knowledge, Information）APIを使用して、2023年7月1日から2023年7月31日までの太陽フレアのデータを取得するPythonスクリプトです。

取得したデータは、太陽フレアのID、使用された観測機器、開始時間、ピーク時間、終了時間、クラスタイプ、発生源の位置、活動領域の番号、関連イベント、リンクなど、各太陽フレアに関する詳細な情報を含んでいます。

## グラフ化1

```python
import matplotlib.pyplot as plt
import pandas as pd

# データをDataFrameに変換
df = pd.DataFrame(solar_flare)

# 'peakTime'をdatetime型に変換
df['peakTime'] = pd.to_datetime(df['peakTime'])

# 'classType'の最初の文字（フレアのクラス）を取得
df['class'] = df['classType'].str[0]

# フレアのクラスごとに色を分けるための辞書
color_dict = {'C': 'blue', 'M': 'green', 'X': 'red'}

# 図のサイズを指定
plt.figure(figsize=(20, 10))

# フレアの強度をプロット
for flare_class in ['C', 'M', 'X']:
    subset = df[df['class'] == flare_class]
    plt.scatter(subset['peakTime'], subset['classType'].str[1:].astype(float), color=color_dict[flare_class], label=flare_class)

plt.xlabel('Time')
plt.ylabel('Flare Intensity')

# x軸のラベルを45度回転
plt.xticks(rotation=45)

# レジェンドを追加
plt.legend(title='Flare Class')

# グリッド線を表示
plt.grid(True, linestyle='--', alpha=0.6)

plt.show()

```

![](https://pbs.twimg.com/media/F2hrdu_aQAA60SR?format=png\&name=small)

このコードは、フレアの強度を時間に対してプロットし、フレアのクラス（'C', 'M', 'X'）ごとに色を分けています。

太陽フレアのクラスは、フレアが放出するX線の量に基づいています。具体的には、地球からのX線フラックス（つまり、単位面積あたりのX線の量）を測定し、その値に基づいてフレアを分類します。

フレアのクラスは主に以下の3つです：

1.  **Cクラス**：これらは最も小さなフレアで、地球上の影響はほとんどありません。

2.  **Mクラス**：これらは中程度のフレアで、短期的なラジオブラックアウトを引き起こすことがあります。

3.  **Xクラス**：これらは最も大きなフレアで、大規模なイベントを引き起こす可能性があります。これらは長期的なラジオブラックアウトを引き起こし、地球の大気を擾乱することがあります。

これらのクラスはそれぞれ10倍のスケールで分けられています。つまり、M1はC10の10倍、X1はM10の10倍のX線フラックスを持っています。

## グラフ化2

```python
# ヒートマップを作成しています。色の濃淡で太陽フレアの発生頻度を表現しています。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# データの前処理
df = pd.json_normalize(solar_flare)
df['start_datetime'] = pd.to_datetime(df['beginTime'])
df['start_hour'] = df['start_datetime'].dt.hour  # 開始時間の時間帯

# ヒートマップの作成
heatmap_data = df.groupby([df['start_datetime'].dt.date, df['start_hour']]).size().unstack().fillna(0)
plt.figure(figsize=(10, 10))
sns.heatmap(heatmap_data, cmap='YlGnBu')
plt.title('Frequency of Solar Flares (By Time of Day)')
plt.xlabel('Time of Day')
plt.ylabel('Date')

plt.show()

```

![](https://pbs.twimg.com/media/F2hr0zUbsAA4KTE?format=png\&name=900x900)

## グラフ化3

バブルチャートの作成にはmatplotlibのscatter関数を使用します。

以下は、太陽フレアの開始時間（時間帯）と日付を軸に、発生頻度をバブルの大きさで表現するバブルチャートの作成例です。

```python


import matplotlib.pyplot as plt
import numpy as np

# データの前処理
df['start_date'] = df['start_datetime'].dt.date
df['count'] = 1
bubble_data = df.groupby(['start_date', 'start_hour']).size().reset_index(name='counts')

# バブルチャートの作成
# matplotlibのgrid関数を使用して、グラフに罫線（グリッド）を追加します。

plt.figure(figsize=(10, 10))
plt.scatter(bubble_data['start_hour'], bubble_data['start_date'], s=bubble_data['counts']*100, alpha=0.5)
plt.title('Frequency of Solar Flares (By Time of Day)')
plt.xlabel('Time of Day')
plt.ylabel('Date')

# グリッドの追加（点線）
plt.grid(True, linestyle='--')

plt.show()
```

注意：バブルの大きさは、'counts'の値に100を掛けて調整しています。この値はデータにより適切な値に調整してください。

alphaパラメータはバブルの透明度を設定します。0（完全に透明）から1（全く透明でない）の範囲で設定します。

![](https://pbs.twimg.com/media/F2hsYJ3bQAAFWUi?format=jpg\&name=medium)

***

# 発生源の位置データ

```python
# 発生源の位置データを確認します。

df['sourceLocation'].unique()
```

結果

```python
array([' S22 E57', ' S22 E55', ' N13 W56', ' S12 E39', ' N23 E32',
       ' N16 W80', ' N16 W95', ' S15 E07', ' N15 W90', ' S21 W13',
       ' S13 W49', ' S13 W62', ' N25 E90', ' N25 E89', ' N25 E88',
       ' N26 E88', ' S19 W59', ' S11 W67', ' N25 W54', ' N26 E86',
       ' N22 E60', ' S23 W25', ' S18 E14', ' S25 W40', ' N21 E42',
       ' N21 E41', ' S22 W45', ' N20 E30', ' S25 W50', ' N20 E25',
       ' S25 W60', ' S25 W72', ' N12 E90', ' N27 E35', ' N27 E31',
       ' S21 W87', ' S25 W90', ' S19 W90', ' N25 W50', ' N07 W29',
       ' N28 W25', ' N25 W52', ' S11 E41', ' N23 W68', ' N23 W74',
       ' N23 W77', ' N23 W90', ' S25 E75', ' N25 W99', ' N15 E88',
       ' S10 W10', ' S18 E57', ' S20 E43'], dtype=object)
```

さらに確認

```python
print(df['sourceLocation'].head())
```

結果、

```python
0    S22E57
1    S22E55
2    N13W56
3    S12E39
4    N23E32
Name: sourceLocation, dtype: object
```

## ヒートマップの作成

```python
df['latitude'] = df['sourceLocation'].str.slice(start=0, stop=3)
df['longitude'] = df['sourceLocation'].str.slice(start=3)

# 緯度と経度を数値に変換します。
df['latitude'] = df['latitude'].apply(lambda x: int(x[1:]) if 'N' in x else -int(x[1:]))
df['longitude'] = df['longitude'].apply(lambda x: int(x[1:]) if 'E' in x else -int(x[1:]))

import numpy as np

# ヒートマップの作成
heatmap_data = pd.pivot_table(df, values='sourceLocation', index=['latitude'], columns='longitude', aggfunc=np.size, fill_value=0)

plt.figure(figsize=(10, 10))
sns.heatmap(heatmap_data, cmap='YlGnBu')
plt.title('Geographical Heatmap of Solar Flare Origins')
plt.xlabel('Longitude')
plt.ylabel('Latitude')

plt.show()

```

![](https://pbs.twimg.com/media/F2htTJqaIAATrQI?format=png\&name=small)

このコードは、緯度と経度を基に太陽フレアの発生源のヒートマップを作成します。ヒートマップの色の濃淡は、その地点での太陽フレアの発生頻度を表します。