今回は地震データの可視化についてです
最近地震が多いので、plotlyで可視化してみました。
解説動画はこちら
データの入手先
気象庁の地震データベース
コードを動かしてみたい方は
CSVがダウンロードできるようなので
手元にダウンロードしてみてください。
データの読み込み
こちらのコードはGoogle Colabで動くようになっています。
動かしたい場合は Colabの画面左メニューから
フォルダマークをクリックすると
ファイル置き場が見えるので、そこにCSVファイルを
ドラッグなどで配置します。
ファイルを読み込みするには下記のコードです。
df変数にデータが読み込まれると思います。
データの整形
CSVそのままのデータでは
うまく可視化が行えないため
可視化用にデータを加工する必要があります。
下記のコードを実行すると
可視化用のカラムなどが追加されます。
時系列の可視化
最初は時系列で
どれだけ地震が発生しているのかを
見てみましょう
日別、震度別で時系列で地震の回数を
表示してみます。

データは直近の1週間分しか無いようです。
7月前後で急増しているのが分かります。
箱ひげ図の可視化
地図表示
今後は地図で震度を表示してみましょう
OpenStreetMapを使用して、緯度軽度を用いて
地図に震度を表示させてみます。

今回の地震は、かなり局所的に起きていることが分かります。
特に震度5以上が発生した箇所がかなり近く
この近辺は注意が必要な地域に見えます。
散布図表示
最後に
マグニチュード、震度、深さを
散布図で見てみましょう

どの深さでも、満遍なく起きているように見えますね
地震自体は、いつ何時、どこでも起きてしまいます。
まとめ
緯度経度が記載されているデータは
plotlyなどを用いれば地図表示が比較的
簡単に行うことができます。
可視化の表現の幅が広がるので
覚えておくと良いかもしれませんね
今日はここまでです
それでは
最近地震が多いので、plotlyで可視化してみました。
解説動画はこちら
データの入手先
気象庁の地震データベース
コードを動かしてみたい方は
CSVがダウンロードできるようなので
手元にダウンロードしてみてください。
データの読み込み
こちらのコードはGoogle Colabで動くようになっています。
動かしたい場合は Colabの画面左メニューから
フォルダマークをクリックすると
ファイル置き場が見えるので、そこにCSVファイルを
ドラッグなどで配置します。
ファイルを読み込みするには下記のコードです。
# 必要なライブラリのインポート
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import warnings
warnings.filterwarnings('ignore')
file_path = "/content/地震リスト.csv"
df = pd.read_csv(file_path)
df.head()
df変数にデータが読み込まれると思います。
データの整形
CSVそのままのデータでは
うまく可視化が行えないため
可視化用にデータを加工する必要があります。
下記のコードを実行すると
可視化用のカラムなどが追加されます。
# データの前処理
s_order = ['震度1', '震度2', '震度3', '震度4', '震度5弱', '震度5強', '震度6弱', '震度6強', '震度7']
target = "トカラ列島近海"
def preprocess_data(df):
# 緯度・経度の変換(度分秒から度へ)
def convert_coordinate(coord_str):
# 例: "29°28.2′N" -> 29.47
if '°' in coord_str and '′' in coord_str:
parts = coord_str.replace('N', '').replace('E', '').replace('S', '').replace('W', '')
degree_part = parts.split('°')[0]
minute_part = parts.split('°')[1].replace('′', '')
return float(degree_part) + float(minute_part) / 60
return float(coord_str)
df['緯度_数値'] = df['緯度'].apply(convert_coordinate)
df['経度_数値'] = df['経度'].apply(convert_coordinate)
# 深さの数値化
df['深さ_数値'] = df['深さ'].str.replace(' km', '').astype(float)
# 震度の数値化
s_mapping = {
'震度1': 1, '震度2': 2, '震度3': 3, '震度4': 4, '震度5弱': 5,
'震度5強': 5.5, '震度6弱': 6, '震度6強': 6.5, '震度7': 7
}
df['最大震度_数値'] = df['最大震度'].map(s_mapping)
df['最大震度'] = pd.Categorical(df['最大震度'], categories=s_order, ordered=True)
return df
# データの前処理を実行
df = preprocess_data(df)
df = df[df["震央地名"]==target]
df.head()
時系列の可視化
最初は時系列で
どれだけ地震が発生しているのかを
見てみましょう
日別、震度別で時系列で地震の回数を
表示してみます。
# 時系列分析(日付別)
df['日付'] = pd.to_datetime(df['地震の発生日'])
daily_shindo_counts = df.groupby(['日付', '最大震度']).size().reset_index(name='地震回数')
# 震度の順序を維持
daily_shindo_counts['最大震度'] = pd.Categorical(
daily_shindo_counts['最大震度'],
categories=s_order,
ordered=True
)
# 震度別横並び棒グラフ
fig_time = px.bar(
daily_shindo_counts,
x='日付',
y='地震回数',
color='最大震度',
title='日付別地震発生回数(震度別)',
labels={'地震回数': '地震発生回数', '日付': '発生日'},
category_orders={'最大震度': s_order},
barmode='group' # 横並びに表示
)
# レイアウトの調整
fig_time.update_layout(
xaxis_tickangle=-45,
height=600,
width=1000,
legend=dict(
orientation="v",
yanchor="top",
y=1,
xanchor="left",
x=1.01
)
)
fig_time.show()

データは直近の1週間分しか無いようです。
7月前後で急増しているのが分かります。
箱ひげ図の可視化
次は箱ひげ図で
「トカラ列島近海」の詳細を見てみましょう。
震度ごとにマグニチュードをまとめると
このような感じになります。

同じ震度でも、マグニチュードにはバラツキがありますが
マグニチュードが上がるにつれ、震度も大きくなっています。
「トカラ列島近海」の詳細を見てみましょう。
震度ごとにマグニチュードをまとめると
このような感じになります。
# 震央地名 最大震度別での箱ひげ図
fig_box = px.box(df,
x='震央地名',
y='M',
color='最大震度',
title='震央地名別 マグニチュード分布(最大震度別)',
labels={'M': 'マグニチュード', '震央地名': '震央地名'},
category_orders={'最大震度': s_order})
fig_box.update_layout(
xaxis_tickangle=-45,
height=600,
width=1000
)
fig_box.show()

同じ震度でも、マグニチュードにはバラツキがありますが
マグニチュードが上がるにつれ、震度も大きくなっています。
地図表示
今後は地図で震度を表示してみましょう
OpenStreetMapを使用して、緯度軽度を用いて
地図に震度を表示させてみます。
# マップ表示用のデータ準備
df_map = df.copy()
df_map['緯度_数値'] = pd.to_numeric(df_map['緯度_数値'], errors='coerce')
df_map['経度_数値'] = pd.to_numeric(df_map['経度_数値'], errors='coerce')
df_map['M'] = pd.to_numeric(df_map['M'], errors='coerce')
df_map = df_map.dropna(subset=['緯度_数値', '経度_数値', 'M'])
df_map['最大震度'] = pd.Categorical(df_map['最大震度'], categories=s_order, ordered=True)
# 緯度経度と最大震度・Mを用いたmap表示(OpenStreetMap使用)
fig_map2 = go.Figure()
# 震度別に色分けしてプロット
震度_colors = {
'震度1': '#90EE90', # 薄緑
'震度2': '#FFD700', # 金色
'震度3': '#FFA500', # オレンジ
'震度4': '#FF6347', # トマト色
'震度5弱': '#FF4500', # 赤オレンジ
'震度5強': '#FF0000', # 赤
'震度6弱': '#8B0000', # 濃い赤
'震度6強': '#4B0082', # インディゴ
'震度7': '#000000' # 黒
}
for 震度 in s_order:
if 震度 in df_map['最大震度'].values:
subset = df_map[df_map['最大震度'] == 震度]
fig_map2.add_trace(go.Scattermapbox(
lat=subset['緯度_数値'],
lon=subset['経度_数値'],
mode='markers',
marker=dict(
size=subset['最大震度_数値'] ** 2 , # サイズ調整
color=震度_colors.get(震度, '#000000'),
sizemode='diameter'
),
text=subset['震央地名'],
hovertemplate='%{text}
' +
'緯度: %{lat:.2f}
' +
'経度: %{lon:.2f}
' +
'マグニチュード: %{customdata[0]}
' +
'最大震度: %{customdata[1]}
' +
' ',
customdata=list(zip(subset['M'], subset['最大震度'])),
name=震度
))
fig_map2.update_layout(
title='地震発生位置(最大震度・マグニチュード)- OpenStreetMap',
mapbox=dict(
style="open-street-map",
center=dict(lat=df_map['緯度_数値'].mean(), lon=df_map['経度_数値'].mean()),
zoom=8
),
height=700,
width=1000
)
fig_map2.show()

今回の地震は、かなり局所的に起きていることが分かります。
特に震度5以上が発生した箇所がかなり近く
この近辺は注意が必要な地域に見えます。
散布図表示
最後に
マグニチュード、震度、深さを
散布図で見てみましょう
# 深さとマグニチュードの関係
fig_scatter = px.scatter(
df,
x='深さ_数値',
y='M',
color='最大震度',
size='最大震度_数値',
hover_name='震央地名',
hover_data={
'地震の発生日': True,
'地震の発生時刻': True
},
title='深さとマグニチュードの関係(最大震度別)',
labels={'深さ_数値': '深さ (km)', 'M': 'マグニチュード'},
category_orders={'最大震度': s_order}
)
fig_scatter.show()

どの深さでも、満遍なく起きているように見えますね
地震自体は、いつ何時、どこでも起きてしまいます。
まとめ
緯度経度が記載されているデータは
plotlyなどを用いれば地図表示が比較的
簡単に行うことができます。
可視化の表現の幅が広がるので
覚えておくと良いかもしれませんね
今日はここまでです
それでは








