海面水温#

海洋は地球表面の約7割を占め,大気と相互作用をしています。特に海面水温は,下面境界条件として気象に大きな影響を与え,その偏差は異常天候の要因の一つです。気象庁の高解像度海面水温データMGDSSTを可視化してみましょう。 MGDSSTはNEAR-GOOS RRTDBから提供されています。

Readmeによると,ファイルは日別に提供されており,解像度は0.25度です。721行からなり最初の行はデータの日,月,年,行と列の数が記されています。2行目の1列目が東経0.125度, 北緯89.875度で,721行目の1440列目が東経359.875度, 南緯89.875度おける値を表しています。つまりデータは北から南に,グリニッジ子午線から東向き並んでいます。

import requests
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import xarray as xr


nlon, nlat = 1440, 720
lon = np.linspace(0.125, 359.875, nlon)
lat = np.linspace(89.875, -89.875, nlat)
year = 2019
month = 10
day = 10
fname = f"re_mgd_sst_glb_D{year}{month:02}{day:02}.txt.gz"
url = f"https://www.data.jma.go.jp/gmd/goos/data/pub/JMA-product/mgd_sst_glb_D/{year}/{fname}"
with requests.get(url) as response:
    with open(fname, "wb") as f:
        f.write(response.content)

Note

Pythonのrequestsの代わりにシェルのcurlコマンドを使うこともできます。

!curl -O $url

pandasで表形式のテキストファイルを読む場合はread_csv()を使うことが多いのですが,MGDSSTの各要素は長さ3文字の固定長になのでpandas.read_fwf()を使います。ヘッダ行をskiprowsで一つ読み飛ばし,ヘッダ行なし(header=None)で180行(nrows=nlat)読みます。888999はそれぞれ海氷と陸を表しているので非数とします。ただし,最近のデータは速報解析データ(ファイル名mgd_sst_glb_Dyyyymmdd.txt.gz)でファイル名の最初にre_がついていません。再解析データ(ファイル名re_mgd_sst_glb_Dyyyymmdd.txt.gz)は,海氷下の海面水温を統計的関係から求めるため,888がなく−1.8℃は海氷100%覆っている海域を表します。ファイルはgzip圧縮されているのでcompression=”gzip”を指定します。unzipコマンドなどで解凍した場合,このオプションは使用しません。

df = pd.read_fwf(fname, widths=[3]*nlon, skiprows=1, header=None,
                 na_values=[888, 999], nrows=nlat, compression="gzip")

データは10倍した整数で表されているので,0.1倍し,経度・緯度座標を付加したxarrayのDataArrayに変換します。ただし2019年以前の再解析データの場合は0.1倍されていません。

xarrayはラベルつきの多次元データを扱うライブラリです。Numpyの配列にpandasのようなラベルをつけて扱うことができます。海面水温データに対しては,経度と緯度を付加します。pandasのDataFrame同様,xarrayのDataArrayplot()メソッドでデータを可視化することができます。`

sst = xr.DataArray(df * 0.1, dims=["lat", "lon"], coords={"lat":lat, "lon":lon})
sst.plot(figsize=[9,5], vmin=-1.8, vmax=30)
plt.show()
_images/28207d3a75a7db4a7590d1d0bbbb2cc7417bbacba1d3458d23cf48900d217946.png