「全球及び日本域150年連続実験データ」を可視化する その7-札幌の平均気温のシミュレーション結果をヒートマップで表現する。
はじめに
今年の夏は北海道でもうだるような暑さが続きました。気象庁の”夏の天候のまとめ”によれば、2023年(令和5年)夏(6~8月)の日本の平均気温は1898年以降で夏として最も高くなったとのこと。
別紙(概況、統計値等)によれば、北海道の平均気温は平年より3℃も高かったらしい。
https://www.data.jma.go.jp/obd/stats/data/stat/tenko2023jja_besshi.pdf
実際、これまでに経験したことのない暑さだったことは間違いないのですが、気温の変化をよりわかりすく示すヒートマップというものがあるようです
これはわかりやすい!ということで、150連続実験データでもこの表現手法を使ってヒートマップを作成してみたいと思います。
データの切り出し
ここでは1例として札幌管区気象台に最も近い格子点における8月の平均気温のヒートマップを作成します。
地理座標は北緯43度3.6分、東経141度19.7分ですので、対応する格子点の位置を特定します。
https://www.jma.go.jp/jma/kishou/know/amedas/ame_master.pdf
# ライブラリをインポート import os import numpy as np import pandas as pd import geopandas as gpd from shapely.geometry import Polygon os.chdir("/mnt/c/Users/hoge/ONEFIFTY") # 札幌管区気象台の緯度経度 src_lat = 43 + 3.6/60 src_lon = 141 + 19.7/60 # 日本域20㎞150年連続実験データの投影法での座標を計算 wgs_SRS = osr.SpatialReference() wgs_SRS.ImportFromEPSG(4326) lcc_SRS = osr.SpatialReference() lcc_SRS.ImportFromProj4( "+proj=lcc +lat_1=30.0 +lat_2=60.0 +lon_0=135. +lat_0=0 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs") trans = osr.CoordinateTransformation(wgs_SRS,lcc_SRS) out_x,out_y,z = trans.TransformPoint(src_lat,src_lon) #最も近い格子点の行番号、列番号を特定する x_vec = (-1930000.1287495417 + 10000) + np.arange(0,191) * 20000 y_vec = ((5833346.794147097 - 10000) - np.arange(0,155) * 20000)[::-1] x_ind = np.argmin(np.abs(x_vec - out_x)) y_ind = np.argmin(np.abs(y_vec - out_y)) # 確認のためのベクタを作成する x = x_vec[x_ind] y = y_vec[y_ind] df = pd.DataFrame(["Sapporo"]) df.columns=["name"] gm = [Polygon([(x-10000,y-10000),(x-10000,y+10000),(x+10000,y+10000),(x+10000,y-10000),(x-10000,y-10000)])] sapporo_gdf = gpd.GeoDataFrame(df,geometry=gm,crs=lcc_SRS.ExportToWkt()) sapporo_gdf.to_crs("EPSG:4326").to_file("sappro_grid.fgb", driver="FlatGeobuf") print(x_ind,y_ind) # 121 121
格子点を中心とした20㎞メッシュに札幌が含まれていることが確認できます。
150年連続実験データの処理
「全球及び日本域150年連続実験データ」の20km150年連続実験データから、(121,121)に位置するデータを切り出し、地上気温の日平均値を計算します。
# ライブラリをインポート import os import pathlib import numpy as np import pandas as pd import xarray as xr import rioxarray # 処理するファイルの一覧を作成する os.chdir("/mnt/c/Users/hoge/ONEFIFTY") griblist_df = pd.DataFrame({"grib_path":list(pathlib.Path("./").glob("**/*.grib"))}) griblist_df["grib_name"] = griblist_df["grib_path"].map(lambda x: x.name) griblist_df["year"] = griblist_df["grib_name"].str.extract(".*_(\d{4})\d{2}.grib").astype(int) griblist_df["month"] = griblist_df["grib_name"].str.extract(".*_\d{4}(\d{2}).grib").astype(int) griblist_df = griblist_df.sort_values("year").reset_index(drop=True) # 年ごとの日平均値を収納する配列を作成 TA_daily_mean_arr = np.zeros((griblist_df.shape[0],31)) # 年ごとに日平均値を計算 for h_index,h_row in griblist_df.iterrows(): ds = xr.open_dataset(h_row["grib_path"], engine="cfgrib") ds["time"] = ds["time"] - np.timedelta64(1, 'h') da = ds["t"][:,121,121].resample(time='1D').mean() TA_daily_mean_arr[h_index,:] = da.data np.save("TA_daily_mean.npy",TA_daily_mean_arr)
ヒートマップの作成
plotlyでヒートマップを描きます。
# ライブラリをインポート import os import numpy as np import plotly.express as px import matplotlib.cm as cm os.chdir("/mnt/c/Users/hoge/ONEFIFTY") # データをロード TA_daily_mean_arr = np.load("TA_daily_mean.npy") # 平年値(統計期間1991~2020年)を計算 TA_normal = TA_daily_mean_arr[40:70,:].mean() # ヒートマップの描画 fig = px.imshow(TA_daily_mean_arr, aspect="auto",width=550,height=800, color_continuous_scale='RdBu_r', color_continuous_midpoint=TA_normal) # レイアウト編集 fig.update_layout( title=dict(text="札幌周辺の8月の日平均気温シミュレーション(1951~2099)", y=0.98), margin=dict(t=40, b=45, l=25, r=120) ) #脚注1を作成 fig.add_annotation( font_size=10, font_family="sans-serif", x=1.04, y=0.83, xref="paper", yref="paper", xanchor="left", yanchor="top", borderwidth=1, bordercolor='black', align="left", text="「日本域150年連続<br>実験」による、札幌<br>に最も近い格子点に<br> おける1951年から<br>2099年までの8月の<br>日平均気温シミュレ<br> ーション結果。縦軸<br>が '年' , 横軸が '月日' 。<br>8月の日平均気温の<br> 平年値(1991~2020<br>年)を白とし、高温<br>を赤、低温を青とし<br> た色分けにより気温<br>の違いを表現した。<br>結果は特定の日の「<br> 気象」の状態(何月<br>何日に気温は何度か)<br>を予測しているもの<br> ではないことに注意!" ) # 脚注2を作成 fig.add_annotation( font_size=10, font_family="sans-serif", x=1.03, y=0.12, xref="paper", yref="paper", xanchor="left", yanchor="top", align="left", showarrow=False, text="本ヒートマップは、<br>文部科学省「統合<br>的気候モデル高度<br> 化研究プログラム」<br>において、地球シ<br>ミュレータを用い<br> て作成されたデー<br>タを使用させてい<br>ただいています。" ) # y軸を設定 fig.update_yaxes( tickvals=[0,9,19,29,39,49,59,69,79,89,99,109,119,129,139,148], ticktext=["1951","1960","1970","1980","1990","2000","2010","2020","2030","2040","2050","2060","2070","2080","2090","2099"] ) # x軸を設定 fig.update_xaxes( tickvals=[0,4,9,14,19,24,29], ticktext=["08/01","08/05","08/10","08/15","08/20","08/25","08/30"], tickangle=-50 ) # カラーバーを設定 fig.update_coloraxes( colorbar_len=0.4, colorbar_y=0.32, colorbar_yanchor="middle", colorbar_ticklabeloverflow="allow", colorbar_tickvals=[284,310], colorbar_ticktext=["low","high"], colorbar_title="日平均気温", colorbar_title_side="top" ) # ロゴを描画 fig.add_layout_image( sizex=0.2,sizey=0.2, source="https://pbs.twimg.com/profile_images/1664190624701222912/8gaaJj-l_400x400.png", xref="paper", yref="paper", x=1.05, y=0.995) fig.show()
ヒートマップができました。
皆さんのお住まいの地域でも同様のヒートマップを作成することができます。
「全球及び日本域150年連続実験データ」の日本域20km150年連続実験データの日平均気温をヒートマップで表現する方法を紹介しました。試してみてくださいね~。
※本記事では文部科学省「統合的気候モデル高度化研究プログラム」において、地球シミュレータを用いて作成されたデータを使用しました。