Pythonで複数の台風経路を一括に日本地図にプロットする

今回は、Pythonを使って台風経路を描写する方法を紹介したいと思います。QGISでも同様のことができますが、csvなどの経路データを一括で読み込んで変換する際、結局pythonコンソールを使わなくてはいけないので、もしかしたらPythonのみで作成した方がスムーズにできるのではないかと思いチャレンジしてみました。

今回使用するコードは下記になります。参考になれば幸いです。

  • Jsonデータから緯度経度を抜き出しcsvに変換する(台風データ専用)
  • shapeデータを描写する
  • 緯度経度のcsvデータをつなげて線にし描写する

1.地図データのダウンロード

国土数値情報ダウンロードサイト(https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-v2_4.html)から地図データをダウンロードします。全国でもいいですがデータが重いので、必要な県のみでもいいと思います。今後もデータを提供していただけるように、アンケートは必ず回答しましょう。

2.台風データのダウンロード

デジタル台風(http://agora.ex.nii.ac.jp/digital-typhoon/year/)より台風データをダウンロードします。データ形式がJsonなので、一度変換する必要があります。

今回は2022年のデータを3つほど使っていきたいと思います。

日本付近を通過している台風1、4、8号を使用します。

「GeoJson」を右クリックし「名前を付けてリンク先を保存」を選択します。

3.Jsonをcsvに変換する

JsonデータだとPythonでは使えないので(何かしら方法はあると思いますが…)、csvデータに変換します。

import os
import json
import csv
 
# 入力ディレクトリと出力ディレクトリのパスを設定します
input_directory = '入力ディレクトリのパス'
output_directory = '出力ディレクトリのパス'
 
if not os.path.exists(output_directory):
    os.makedirs(output_directory)

for filename in os.listdir(input_directory):
    if filename.endswith('.json'):
        file_path = os.path.join(input_directory, filename)
 
        output_file = os.path.join(output_directory, f'{os.path.splitext(filename)[0]}.csv')
 
        with open(output_file, 'w', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            writer.writerow(['Latitude', 'Longitude'])
 
            with open(file_path, encoding='utf-8') as json_file:
                data = json.load(json_file)
 
                features = data['features']
                for feature in features:
                    geometry = feature['geometry']
                    if geometry['type'] == 'Point':
                        coordinates = geometry['coordinates']
                        writer.writerow(coordinates)
 
print('CSVファイルの出力が完了しました。')

上記のコードはJsonデータから時間ごとの緯度経度を抽出してcsvに変換しています。デジタル台風専用に作成したものなので、他のデータでは使えない可能性が高いです。

こんな感じのデータになっていれば成功です!

4.台風の経路を地図と重ねて表示してみる

下準備が終わりましたので、本題の台風経路の表示をしてみます。コードは下記になります。

import geopandas as gpd
from shapely.geometry import LineString
import matplotlib.pyplot as plt
import pandas as pd
import glob

# CSVファイルから座標データを読み込む
files = glob.glob('○○○○○○○○\台風データ\*.csv')
fp = '○○○○○○○○\N03-20200101_GML\N03-20_200101.shp'
japan = gpd.read_file(fp, encoding="cp932")

lines = []

for file in files:
    df = pd.read_csv(file, encoding="shift-jis")
    line = LineString(df[['Latitude', 'Longitude']].values)
    lines.append(line)

gdf = gpd.GeoDataFrame(geometry=lines)

fig, ax = plt.subplots()

japan.plot(ax=ax, edgecolor='gray', facecolor='none')

gdf.plot(ax=ax, color='red')

plt.show()

うまくできていれば画像のように出力されるはずです。

以下の点に注意してください。

  • 「geopandas」は事前にインストールする必要があります
  • 16行目はヘッダーを参照しているので、データの1行目の文字と緯度経度を確認してください
  • 出力までに数分かかります(shapeデータの大きさでかなり時間が変わります)

折角なので、少し改造してみます。最終的に画像データにしたいので、画像を出力設定と、描写する緯度経度を指定できるようにします。

import geopandas as gpd
from shapely.geometry import LineString
import matplotlib.pyplot as plt
import pandas as pd
import glob

# CSVファイルから座標データを読み込む
files = glob.glob('○○○○○○○○\台風データ\*.csv')
fp = '○○○○○○○○\N03-20200101_GML\N03-20_200101.shp'
japan = gpd.read_file(fp, encoding="cp932")

lines = []

for file in files:
    df = pd.read_csv(file, encoding="shift-jis")
    line = LineString(df[['Latitude', 'Longitude']].values)
    lines.append(line)

gdf = gpd.GeoDataFrame(geometry=lines)

fig, ax = plt.subplots()

japan.plot(ax=ax, edgecolor='gray', facecolor='none')

gdf.plot(ax=ax, color='red')

plt.xlim(130, 142)  # 経度の範囲
plt.ylim(30, 40)  # 緯度の範囲

# 画像ファイルとして保存
plt.savefig('output_image.png', dpi=300)

plt.show()

拡大した図が描写されました!正常に動作していればPythonを使用しているフォルダ(ディレクトリ)に画像が出力されているはずです。

5.おわりに

今回はざっくり手法になりましたが、カラーリストを作って色分けしたり、年度ごとに作成して一括で画像を出力したりと、まだまだ改良の余地はあると思います。今回は台風経路でやりましたが、csvデータを線に変えて描写する機能は、他にもいろいろ使えそうなので、この部分だけでも役立ててもらえれば嬉しいです。

QGISとの比較ですが、Pythonの方がデータの処理スピードや画像の出力面で優れていると感じました。ですが、QGISの方は描写の自由度が高く、操作もしやすいです(結局どちらもコードを使うので難易度はそこそこ高いですが…)。用途に合わせて使い分けていきたいです。

コメント