データ可視化(5) 全球地震散布図の作成:JSON形式
1 か月間に世界中で発生したすべての地震のデータセットをダウンロードし、これらの地震の位置と規模を示す散布図を作成します。これらのデータは JSON 形式で保存されるため、モジュール json を使用して処理します。Plotly は、初心者向けに位置データに基づいて地図を描画するためのツールを提供します。これを使用して、地震の世界的な分布を視覚化し、示します。
1. 地震データ
ファイル eq_data_1_day_m1.json をこの章のプログラムが格納されているフォルダーにコピーしてください。地震はリヒター スケールで測定され、このファイルには、過去 24 時間以内に世界中で発生したマグニチュード 1 以上のすべての地震が (このセクションの執筆時点で) 記録されます。
2. JSONデータを表示する
ファイル eq_data_1_day_m1.json を開くと、その内容が緻密で読みにくいことがわかります。
{
"type":"FeatureCollection","metadata":{
"generated":1550361461000,...
{
"type":"Feature","properties":{
"mag":1.2,"place":"11km NNE of Nor...
{
"type":"Feature","properties":{
"mag":4.3,"place":"69km NNW of Ayn...
{
"type":"Feature","properties":{
"mag":3.6,"place":"126km SSE of Co...
{
"type":"Feature","properties":{
"mag":2.1,"place":"21km NNW of Teh...
{
"type":"Feature","properties":{
"mag":4,"place":"57km SSW of Kakto...
--snip--
これらのデータは、人間ではなく機械による読み取りに適しています。ただし、ご覧のとおり、このファイルにはいくつかの辞書と、大きさや位置などの関心のある情報が含まれています。
モジュール json は、JSON データを探索および操作するためのさまざまなツールを提供します。その一部はこのファイルの再フォーマットに役立ち、生データをより明確に確認し、プログラムで処理する方法を決定できるようになります。
まずこのデータをロードして、人間が判読できる方法で表示しましょう。このデータ ファイルは非常に長いため、印刷する代わりに、データを別のファイルに書き込み、そのファイルを開いてデータ内を簡単に移動できます: eq_explore_data.py
import json
# 探索数据的结构。
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
❶ all_eq_data = json.load(f)
❷ readable_file = 'data/readable_eq_data.json'
with open(readable_file, 'w') as f:
❸ json.dump(all_eq_data, f, indent=4)
まずモジュール json をインポートして、ファイル内のデータが適切にロードされ、all_eq_data に保存されるようにします (❶を参照)。関数 json.load() は、データを Python が処理できる形式に変換します。これは巨大な辞書です。❷では、このデータを人間が読める形式で書き込むファイルを作成します。関数 json.dump() は、JSON データ オブジェクトとファイル オブジェクトを受け取り、データをこのファイルに書き込みます (❸を参照)。パラメータ indent=4 は、データ構造に一致するインデント量を使用してデータをフォーマットするように dump() に指示します。
ここで、ディレクトリ data を調べ、その中のファイル readable_eq_data.json を開くと、その先頭が次のようになっていることがわかります: readable_eq_data.json
{
"type": "FeatureCollection",
❶ "metadata": {
"generated": 1550361461000,
"url": "https://earthquake.usgs.gov/earthquakes/.../1.0_day.geojson",
"title": "USGS Magnitude 1.0+ Earthquakes, Past Day",
"status": 200,
"api": "1.7.0",
"count": 158
},
❷ "features": [
--snip--
このファイルの先頭は、データ ファイルがいつ生成されたか、およびインターネット上のどこで見つかるかを示すキー「メタデータ」(❶を参照) を持つフラグメントです。また、人間が読めるタイトルと、ファイルに記録された地震の数も含まれています。過去 24 時間で 158 件の地震がありました。
この geoJSON ファイルの構造は、位置ベースのデータの保存に適しています。データは、主要な「特徴」に関連付けられたリストに保存されます(❷を参照)。このファイルには地震データが含まれているため、リストの各要素は地震に対応します。この構造は少しわかりにくいかもしれませんが、これは便利で、地質学者は各地震に関する任意の量の情報を辞書に保存し、それらの辞書を大きなリストに入れることができます。
特定の地震を表す辞書を見てみましょう: readable_eq_data.json
--snip--
{
"type": "Feature",
❶ "properties": {
"mag": 0.96,
--snip--
❷ "title": "M 1.0 - 8km NE of Aguanga, CA"
},
❸ "geometry": {
"type": "Point",
"coordinates": [
❹ -116.7941667,
❺ 33.4863333,
3.22
]
},
"id": "ci37532978"
},
重要な「特性」は、特定の地震に関する大量の情報に関連付けられています(❶を参照)。私たちは主に、キー「マグ」に関連付けられた地震のマグニチュードと地震のタイトルに関心があります。後者は、地震のマグニチュードと位置の概要を示しているためです (❷を参照)。
重要な「形状」は地震が発生した場所を示します (❸を参照)。この情報に基づいて散布図上で地震をマークする必要があります。キーの「座標」に関連付けられたリストでは、地震が発生した場所の経度 (❹ を参照) と緯度 (❺ を参照) を見つけることができます。
このファイルには、私たちが書いたコードよりも多くのネスト レベルが含まれています。混乱しても心配しないでください。複雑な作業のほとんどは Python が処理します。一度に扱うのは 1 レベルまたは 2 レベルのネストだけです。まず、過去 24 時間に発生した各地震の辞書を抽出します。
場所について話すときは、通常、最初に緯度、次に経度について話します。この習慣の理由は、人類が経度の概念ができるずっと前に緯度を最初に発見したためである可能性があります。ただし、多くの地質学の枠組みでは、経度が最初にリストされ、緯度が最後にリストされます。これは、これが数学的規則と一致しているためです[図示]。geoJSON 形式は (経度、緯度) の規則に従いますが、他のフレームワークを使用する場合は、従う規則に注意することが重要です。
3. 地震のリストを作成する
まず、すべての地震に関するさまざまな情報を含むリストを作成します: eq_explore_data.py
import json
# 探索数据的结构。
filename = 'data/eq_data_1_day_m1.json'
with open(filename) as f:
all_eq_data = json.load(f)
all_eq_dicts = all_eq_data['features']
print(len(all_eq_dicts))
キー「機能」に関連付けられたデータを抽出し、all_eq_dicts に保存します。このファイルには 158 件の地震が記録されていることがわかっています。次の出力は、このファイルに記録されたすべての地震を抽出したことを示しています。
158
私たちが書いたコードは非常に短いことに注意してください。整形式のファイル readable_eq_data.json には 6000 行以上が含まれていますが、わずか数行のコードで、すべてのデータを読み取って Python リストに保存できます。以下はすべての地震のマグニチュードを抽出します。
4. マグニチュードを抽出する
すべての地震データのリストが得られたので、リストを反復処理して必要なデータを抽出できます。各地震のマグニチュードを抽出しましょう: eq_explore_data.py
--snip--
all_eq_dicts = all_eq_data['features']
❶ mags = []
for eq_dict in all_eq_dicts:
❷ mag = eq_dict['properties']['mag']
mags.append(mag)
print(mags[:10])
地震のマグニチュードを保存する空のリストを作成し、リスト all_eq_dicts を反復処理します (❶を参照)。各地震のマグニチュードは、対応する辞書の「プロパティ」セクションの「マグ」キーの下に保存されます (❷を参照)。次に、地震のマグニチュードを変数 mag に割り当て、この変数をリスト mag の最後に追加します。
抽出されたデータが正しいことを確認するには、最初の 10 個の地震のマグニチュードを出力します。
[0.96, 1.2, 4.3, 3.6, 2.1, 4, 1.06, 2.3, 4.9, 1.8]
次に、各地震の位置情報を抽出し、地震散布図を描画します。
5. 位置データの抽出
位置データは「geometry」キーの下に保存されます。「ジオメトリ」キーに関連付けられた辞書には、リストに関連付けられた「座標」キーがあり、リストの最初の 2 つの値は経度と緯度です。以下は、位置データを抽出する方法を示しています: eq_explore_data.py
--snip--
all_eq_dicts = all_eq_data['features']
mags, titles, lons, lats = [], [], [], []
for eq_dict in all_eq_dicts:
mag = eq_dict['properties']['mag']
❶ title = eq_dict['properties']['title']
❷ lon = eq_dict['geometry']['coordinates'][0]
lat = eq_dict['geometry']['coordinates'][1]
mags.append(mag)
titles.append(title)
lons.append(lon)
lats.append(lat)
print(mags[:10])
print(titles[:2])
print(lons[:5])
print(lats[:5])
場所のタイトルを格納するリスト title を作成し、辞書「プロパティ」(❶を参照) の「タイトル」キーに対応する値を抽出し、経度と緯度を格納するリストを作成します。コード eq_dict['geometry'] は、「geometry」キーに関連付けられた辞書にアクセスします (❷を参照)。2 番目のキー (「座標」) は「座標」に関連付けられたリストを取得し、インデックス 0 はそのリストの最初の値、つまり地震が発生した場所の経度を取得します。
最初の 5 つの経度と緯度を出力すると、抽出されたデータが正しいことが出力に示されます。
[0.96, 1.2, 4.3, 3.6, 2.1, 4, 1.06, 2.3, 4.9, 1.8]
['M 1.0 - 8km NE of Aguanga, CA', 'M 1.2 - 11km NNE of North Nenana, Alaska']
[-116.7941667, -148.9865, -74.2343, -161.6801, -118.5316667]
[33.4863333, 64.6673, -12.1025, 54.2232, 35.3098333]
6. 振幅散布図を描く
先ほど抽出したデータを使用して、視覚化を描画できます。まず単純な振幅散布図を実装し、正しい情報が表示されていることを確認した後、スタイルと外観に注目します。初期散布図を描画するコードは次のとおりです: eq_world_map.py
❶ import plotly.express as px
fig = px.scatter(
x=lons,
y=lats,
labels={
"x": "经度", "y": "纬度"},
range_x=[-200, 200],
range_y=[-90, 90],
width=800,
height=800,
title="全球地震散点图",
❷ )
❸ fig.write_html("global_earthquakes.html")
❹ fig.show()
まず、px というエイリアスで示される、plotly.express をインポートします。Plotly Express は Plotly の高レベル インターフェイスであり、使いやすく、Matplotlib (❶ を参照) に似た構文を備えています。次に、 px.scatter 関数を呼び出してパラメータを設定して図インスタンスを作成し、[イラスト] 軸を経度に設定します [範囲は [-200, 200] (スペースを拡張して、180° 付近の地震散乱点を完全に表示します) [図] 軸は緯度[範囲は[-90,90]]、散布図表示の幅と高さを800ピクセル、タイトルを「全球地震散布図」に設定」(❷参照)。
わずか 14 行のコードで、fig オブジェクトを返す単純な散布図が構成されます。fig.write_html メソッドは、ビジュアライゼーションを HTML ファイルとして保存できます。フォルダー内で global_earthquakes.html ファイルを見つけ、ブラウザで開きます (❸を参照)。また、Jupyter Notebook を使用している場合は、fig.show メソッドを直接使用して、ノートブックのセルに散布図を直接表示できます (❹ を参照)。
局所的な効果を次の図に示します。
この散布図は、より有意義で理解しやすいものにするために大幅に変更できます。これらの変更をいくつか加えてみましょう。
7. チャートデータを指定する別の方法
このグラフを構成する前に、Plotly グラフのデータを指定する少し異なる方法を見てみましょう。現在、緯度と経度のデータは手動で構成されています。
--snip--
x=lons,
y=lats,
labels={
"x": "经度", "y": "纬度"},
--snip--
これは、Plotly Express でチャートのデータを定義する最も簡単な方法の 1 つですが、データ操作には最適ではありません。ここでは、pandas データ分析ツールを使用して、グラフのデータを定義する別の同等の方法を示します。まず、必要なデータをカプセル化する DataFrame を作成します。
import pandas as pd
data = pd.DataFrame(
data=zip(lons, lats, titles, mags), columns=["经度", "纬度", "位置", "震级"]
)
data.head()
次に、パラメータ設定方法を次のように変更できます。
--snip--
data,
x="经度",
y="纬度",
--snip--
このアプローチでは、データに関するすべての情報がキーと値のペアの形式で辞書に配置されます。これらのコードを eq_plot.py で使用すると、結果のプロットは同じになります。この形式では、シームレスなデータ分析が可能になり、以前の形式よりも簡単にカスタマイズできます。