宙畑 Sorabatake

解析ノートブック

岐阜県多治見市が暑い理由と噂される2つの説を気象データと衛星データで確認してみた

ニュースでその名前を見ることも少なくない岐阜県多治見市について、なぜ日本トップレベルに暑い街なのか、2つの説をデータをもとに考察してみました。

2022年8月31日以降、Tellus OSでのデータの閲覧方法など使い方が一部変更になっております。新しいTellus OSの基本操作は以下のリンクをご参照ください。
https://www.tellusxdp.com/ja/howtouse/tellus_os/start_tellus_os.html

岐阜県多治見市は,埼玉県熊谷市と並び称される猛暑地域として有名な地域。きっとニュースでその名前を見たことがある人も多いのではないでしょうか。そこで、多治見市がどうしてこれほど暑くなるのか、その要因をTellusのデータを使って検証してみました。

(1)日本の暑い街とその要因

岐阜県多治見市は,濃尾平野北東部に位置する盆地的要素を持つ人口約11万人ほどの都市で、美濃焼の産地であり窯業が盛んなことで知られています。また、2007年8月16日には熊谷市と並んで最高気温が40.9℃に達しており、夏場の最高気温がとても暑いことでも知られています。

多治見市がなぜこれほどまで暑いのかについてはいくつかの説がありますが、「ヒートアイランド現象」と「フェーン現象」という2つの自然現象の影響を受けているようです。

ヒートアイランド現象とは、都市部では郊外に比べて気温が下がりにくい現象のことを言います。その要因として都市化に伴う地表の被覆の人工物化、人工排熱の増加、都市の高密度化の3つが大きなものとして挙げられています。

また、フェーン現象とは、山脈を越えて吹く風が山を越える時に水分を失い、反対側の斜面を乾燥した高温の風となって吹き降ろす現象です。一般的に、湿った空気は乾いた空気よりも温度が変化しにくいという特徴があります。湿った空気が山を超える際に冷やされて雨を降らし、その結果乾いた空気となって山を降りる際に元の温度よりも高くなります。

例えば20度だった空気も山を超える際には15度まで冷やされますが、山を降りた後には25度まで温められる、といったことが起こります。このことをフェーン現象と呼びます。

そこで、本記事では、多治見市の気温が高くなる要因として考えられている上記22つの自然現象について、Tellusのデータを使って検証していきます。

(2)検証方法と使用するデータの説明

AMeDASのデータを使うと全国の気象観測所で計測された気象データ(雨量、気温、風速、風向き等)の1分間隔のデータが得られます。

このAMeDASのデータを使って、2017年8月の多治見市を含む東海地方の気温のデータを分析してみたいと思います。

多治見市に近く、より大都市である名古屋の観測所との気温を比較し、多治見市がその他の大都市よりも高い気温を記録しているのはなぜかということについて検証してみます。

また、気温と風向きの関係から、フェーン現象の効果を考察してみたいと思います。

(3)コード解説と検証の結果

1.事前準備-多治見市の気象データの確認-

AMeDASのデータを取得するための関数を定義します。

はじめに必要なライブラリを読み込んでいきます。

import os, requests, json
from skimage import io
from io import BytesIO
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from datetime import datetime, date, timedelta
from time import sleep
%matplotlib inline

各種APIを呼び出すための関数を定義しておきます。
TOKENにはご自身がTellus上で取得したAPIトークンを貼り付けてください。

TOKEN = "ここに自分のトークンを貼り付けてください"

HOST = "https://gisapi.tellusxdp.com"

def get_api_data(url, params={}):
    """
    TellusAPIからデータを取得する
    """
    headers = {
        "content-type": "application/json",
        "Authorization": "Bearer " + TOKEN
    }
    return requests.get(url, headers = headers, params = params)

タイル座標のズームレベル、X軸、Y軸の値から緯度経度を取得する関数を定義します。

def get_tile_bbox(z, x, y):
    """
    タイル座標からバウンディングボックスを取得する
    https://tools.ietf.org/html/rfc7946#section-5
    Parameters
    ----------
    z : int 
        タイルのズーム率 
    x : int 
        タイルのX座標 
    y : int 
        タイルのY座標 
    Returns
    -------
    bbox: tuple of number
        タイルのバウンディングボックス
        (左下経度, 左下緯度, 右上経度, 右上緯度)
    """
    def num2deg(xtile, ytile, zoom):
        # https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Python
        n = 2.0 ** zoom
        lon_deg = xtile / n * 360.0 - 180.0
        lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
        lat_deg = math.degrees(lat_rad)
        return (lon_deg, lat_deg)
    
    right_top = num2deg(x + 1, y, z)
    left_bottom = num2deg(x, y + 1, z)
    return (left_bottom[0], left_bottom[1], right_top[0], right_top[1])

AMeDASのAPIからデータを取得する関数を定義します。

def get_amedas_1min(year, month, day, hour, minute, payload={}):
    """
    /api/v1/amedas/1minを叩く

    Parameters
    ----------
    year : string
        西暦年 (4桁の数字で指定) UTC
    month : string
        月 01~12 (2桁の数字で指定) UTC
    day : string
        日 01~31 (2桁の数字で指定) UTC
    hour : string
        時 00~23 (2桁の数字で指定) UTC
    minute : dict
        分 00~59 (2桁の数字で指定) UTC
    payload : dict
        パラメータ(min_lat,min_lon,max_lat,max_lon)
    
    Returns
    -------
    content : list
        結果
    """

    path = '/api/v1/amedas/1min/{}/{}/{}/{}/{}/'.format(year, month, day, hour, minute)
    url = HOST + path
    r = get_api_data(url, params=payload)

    if r.status_code is not 200:
        raise ValueError('status error({}).'.format(r.status_code))
    return json.loads(r.content)  

それでは実際に東海地方の気象観測所のデータを取得してみましょう。

TellusOS上から東海地方が収まるタイルのズームレベル、X軸、Y軸の値を確認してみましょう。

左上の検索窓から「多治見」と入力し、多治見市の位置まで地図を移動させます。メニュー右上の格子状のアイコンをクリックしてタイル座標が表示させます。すると東海地方の座標は(z = 8, x = 225, y = 101)であるということがわかります。

この座標のエリア内の左下および右上の緯度経度を取得してみましょう。

z = 8
x = 225
y = 101
bbox = get_tile_bbox(z, x, y)
# 対象領域の左下の緯度、経度を確認
print(bbox[1], bbox[0])
# 対象領域の右上の緯度、経度を確認
print(bbox[3], bbox[2])

# 東海地方の緯度経度範囲を指定
payload = {
    'min_lon': bbox[0],
    'min_lat': bbox[1],
    'max_lon': bbox[2],
    'max_lat': bbox[3]
}
print(payload)

タイル座標から範囲内の緯度経度が取得できました。

では、実際に範囲内の気象データを取得してみましょう。取得するデータとしては各気象観測所の計測日時、緯度経度に加えて、分析に利用できそうな「雨量」「風力」「風向き」「気温」を取得することにします。

columns = ['station_no', 'datetime', 'rain', 'wind', 'wind_direction', 'temperature', 'lon', 'lat']
df = pd.DataFrame([], columns=columns)


# 2017年8月の東海地方の観測所データを1分間おきに取得する
for day in range(1, 32):
    for hour in range(0, 24):
        for min in range(0, 60):
            amedas_data = get_amedas_1min('2017', '8', str(day), str(hour), str(min), payload)
            amedas_df = pd.DataFrame(list(map(lambda amedas: 
                [
                    str(amedas['station']['prefecture_no']['value']).zfill(2) + str(amedas['station']['observatory_no']['value']).zfill(3),
                    datetime(2017, 8, day, hour = hour, minute = min), # 日時
                    amedas['rain']['intensity']['value'] / 10,           # 雨量
                    amedas['wind']['velocity_ave']['value'] / 10,        # 風量
                    amedas['wind']['direction_ave_16direction']['value'], # 風向き
                    amedas['temperature']['deg']['value'] / 10,    # 気温
                    amedas['coordinates'][0], # 経度
                    amedas['coordinates'][1], # 緯度
                ]
            , amedas_data)), columns=columns)
            # 異常値は0で置換する
            amedas_df.loc[amedas_df['wind'] > 200000000, 'wind'] = 0
            amedas_df.loc[amedas_df['wind_direction'] > 200000000, 'wind_direction'] = 0
            amedas_df.loc[amedas_df['temperature'] > 200000000, 'temperature'] = 0
            df = df.append(amedas_df)
            # APIへの負荷軽減のため、500msごとにアクセスする
            sleep(0.5)

# 日別、時間別の分析がしやすいように、日時と時間を分割して格納する
df[['date', 'time']] = df['datetime'].apply(lambda x: pd.Series(str(x).split()))
df.to_csv('tokai_amedas_data.csv', index = False)

こちらの処理はAPIへの通信が大量に必要となるため非常に時間がかかります(およそ6〜7時間)ので、気長にお待ちいただければと思います。

データが取得できたら読み込み、中身を確認してみます。

df = pd.read_csv('tokai_amedas_data.csv')
# 気温が0度は異常値と思われるため、前後のデータで補完する
df['temperature'] = df['temperature'].replace(0, None).interpolate()

df.head()

多治見市の気象観測所(station_no = 52556)だけを抽出してみます。

# 多治見観測所のデータを抽出
tajimi = df[(df['station_no'] == 52606)]
tajimi.head()

2017年8月のうち、多治見市がもっとも暑かった時間を調べてみます。

# 多治見市がもっとも暑かった時間帯を抽出
tajimi['temperature'].max() # 36.4
tajimi[tajimi['temperature'] == 36.4]

どうやら8月9日の午前5時54分ごろがもっとも暑く36.4度を記録ということがわかります。

ではもっとも暑かった8月9日午前5時54分ごろの他の気象観測所とのデータを比べてみましょう。

# 08/09 05:54:00 のデータだけを抽出
hottest_day = df[df['datetime'] == '2017-08-09 05:54:00']

各気象観測所の位置関係を把握するために、Pythonで地図を描画できるfoliumというライブラリを導入します。

!conda install -y folium
import folium

東海地方の気象観測所を多治見市を中心に地図上にマーカーで表してみましょう。

# 気象観測所(多治見 付近)(?) 緯度: 35.347449 経度: 137.108303 
center_lat = 35.347449
center_lon = 137.108303
map = folium.Map(location=[center_lat, center_lon], zoom_start=11)

for k, v in hottest_day.iterrows():
    folium.Marker([v.lat, v.lon], popup=str(v['station_no']), icon=folium.Icon()).add_to(map)

map

各気象観測所の気温の分布を可視化するために、気温で塗り分けてみます。

map_ = folium.Map(location=[center_lat, center_lon],
                  zoom_start=11,
                  tiles='Stamen Toner')

#温度で色分け
def color(temperature):
    if temperature >= 35:
        return "#FF0405"
    if temperature >= 34:
        return "#FF5000"
    if temperature >= 33:
        return "#FFCE00"
    if temperature >= 32:
        return "#C3FF3C"
    if temperature >= 31:
        return "#38FFC7"
    return "#0000F2"

for k, row in hottest_day.iterrows():
    folium.Circle(radius=2000,
                location=[row['lat'], row['lon']],
                popup="" + str(row['station_no']) + "" + "
" + str(row['temperature']) + "C" + "", color=color(row['temperature']), fill_oacity=0.1, fill=True).add_to(map_) map_

わかりやすさのために青色などの涼しげな色で表現していますが、この時はどの観測所も基本的に30度越の真夏日を記録しています……!

そして、その中でも地図中の突出して気温が高い場所(真っ赤なポイント)が多治見市です。

各気象観測所の位置関係がわかりましたのでここでは多治見市の気温との比較対象として都市部に位置する名古屋観測所と比較して分析していきたいと思います。

対象となる観測所だけを抽出しておきます。

# 多治見観測所:52606
# 名古屋観測所:51106
df = df[df['temperature'] > 0]
tajimi_df = df[(df['station_no'] == 52606)]
nagoya_df = df[(df['station_no'] == 51106)]

# 日付のデータを保持しておく
days = df['date'].unique()

2.ヒートアイランド効果の検証

では、まずはヒートアイランド現象について確認します。

ヒートアイランド現象は都市化が進んでいるほど、気温が下がりにくくなるということは、印象としては名古屋観測所の方がヒートアイランド現象の影響を受けている値になっていると想定されます。
※この時点で多治見市の方がヒートアイランド現象の影響が少ないとなると、多治見市の暑い理由としてヒートアイランド現象が挙げられるのは少し変なのでは?という疑問が生まれています

まずは、多治見観測所と名古屋観測所の1ヶ月の平均気温を比較してみましょう。

# 一日のうちの平均気温を日付単位で抽出
tajimi_mean_temp = tajimi_df[['station_no', 'date', 'temperature']].groupby(['station_no', 'date']).mean()
nagoya_mean_temp = nagoya_df[['station_no', 'date', 'temperature']].groupby(['station_no', 'date']).mean()

plt.figure(figsize=(100, 30))
plt.plot(days, tajimi_mean_temp['temperature'], color="red")
plt.plot(days, nagoya_mean_temp['temperature'], color="blue")
赤色が多治見観測所、緑色が名古屋観測所の平均気温

このデータを見ると名古屋観測所の方が平均気温が高い日が多いようですね。

次に1日あたりの最高気温も確認してみましょう。

# 一日のうちの最高気温を日付単位で抽出
tajimi_max_temp = tajimi_df[['station_no', 'date', 'temperature']].groupby(['station_no', 'date']).max()
nagoya_max_temp = nagoya_df[['station_no', 'date', 'temperature']].groupby(['station_no', 'date']).max()

plt.figure(figsize=(50, 20))
plt.ylabel("temperature", fontsize=36)
plt.yticks(fontsize=36)
plt.plot(days, tajimi_max_temp['temperature'], color="red")
plt.plot(days, nagoya_max_temp['temperature'], color="blue")
赤色が多治見観測所、緑色が名古屋観測所の最高気温

最高気温で比較して見ると、今度は多治見観測所の方が高い日が多いことがわかります。

これらのことから、1日平均すると都市部にある名古屋観測所の方が気温が高いが、瞬間的に最高気温を記録するのは多治見市の方である、ということが言えそうです。

つまり、この時点で、名古屋観測所の方が平均気温と最高気温の差が小さいため、ヒートアイランド現象の影響を受けていることが見えてきました。

もう少し分かりやすくヒートアイランド現象の検証を進めるため、前日と翌日の気温差を調べ、本当に都市部である名古屋観測所ほど気温が変化していないかを確認してみます。

# 前日との気温差を求める
tajimi_diffs = []
for date_str in days[1:]:
    format = "%Y-%m-%d"
    day = datetime.strptime(date_str, format)
    yesterday = day - timedelta(days = 1)
    yesterday_str = yesterday.strftime(format)

    # 前日の最高気温
    tajimi_max_temp = tajimi_df[(tajimi_df['date'] == yesterday_str)]['temperature'].max()
    # 当日の最低気温
    tajimi_min_temp = tajimi_df[(tajimi_df['date'] == yesterday_str)]['temperature'].min()
    # 気温差
    diff = tajimi_max_temp - tajimi_min_temp
    tajimi_diffs.append(diff)

# 初日は前日のデータがないため、全データの平均値を設定しておく
mean = sum(tajimi_diffs) / len(tajimi_diffs)
tajimi_diffs.insert(0, mean)
tajimi_diffs

# 前日との気温差を求める
nagoya_diffs = []
for date_str in days[1:]:
    format = "%Y-%m-%d"
    day = datetime.strptime(date_str, format)
    yesterday = day - timedelta(days = 1)
    yesterday_str = yesterday.strftime(format)

    # 前日の最高気温
    nagoya_max_temp = nagoya_df[(nagoya_df['date'] == yesterday_str)]['temperature'].max()
    # 当日の最低気温
    nagoya_min_temp = nagoya_df[(nagoya_df['date'] == yesterday_str)]['temperature'].min()
    # 気温差
    diff = nagoya_max_temp - nagoya_min_temp
    nagoya_diffs.append(diff)

# 初日は前日のデータがないため、全データの平均値を設定しておく
mean = sum(nagoya_diffs) / len(nagoya_diffs)
nagoya_diffs.insert(0, mean)
nagoya_diffs

計算された気温差をプロットしてみます。

plt.figure(figsize=(50, 20))
plt.ylabel("temperature", fontsize=36)
plt.yticks(fontsize=36)
plt.plot(days, tajimi_diffs, color="red")
plt.plot(days, nagoya_diffs, color="blue")
赤色が多治見観測所、緑色が名古屋観測所の気温差(前日最高気温-当日最低気温)

グラフをみると多治見観測所の方が名古屋観測所より気温差が大きいことがわかります。このことからヒートアイランド現象により、名古屋観測所の周辺は気温の変化が小さい(=常に暑い)のでヒートアイランド現象の影響は名古屋観測所の方がより受けていると言えそうです。

次に、2つの観測所それぞれの、1日の中での気温変化を比べてみます。

多治見市が最高気温を記録した8月9日およびその前後1日を加えた3日間の気温の変化をグラフに表してみます。

days_around_max_day = ['2017-08-08', '2017-08-09', '2017-08-10']
tajimi_max_days = tajimi_df[tajimi_df['date'].isin(days_around_max_day)].set_index('datetime')
nagoya_max_days = nagoya_df[nagoya_df['date'].isin(days_around_max_day)].set_index('datetime')
# 時刻のデータを保持しておく
datetimes = tajimi_max_days.index

plt.figure(figsize=(50, 20))
plt.ylabel("temperature", fontsize=36)
plt.yticks(fontsize=36)
plt.plot(datetimes, tajimi_max_days['temperature'], color="red")
plt.plot(datetimes, nagoya_max_days['temperature'], color="blue")
赤色が多治見観測所、緑色が名古屋観測所の気温変化

このグラフから、多治見観測所の気温の変化は、基本的に夜間にグッと下がり名古屋観測所よりも冷え込んでいることがわかります。この結果は都市化が進むほど気温が下がりにくい、というヒートアイランドの効果とも一致しますね。

また、多治見観測所では日中にグッと気温が上がっていることが読み取れます。やはり、多治見市の気温が高い理由として、ヒートアイランド現象はそこまで関係ないのかもしれません。

次は、もうひとつの影響として考えられているフェーン現象について、気象データと衛星データを用いて考察をしてみたいと思います。

3.フェーン現象の影響の考察-風向き、風力と最高気温の分析-

風と気温の関係を明らかにするために、最高気温を記録した3日間のデータから、多治見観測所の気温と風速の関係をグラフにしてみます。

plt.figure(figsize=(50, 20))
plt.ylabel("temperature", fontsize=36)
plt.yticks(fontsize=36)
plt.subplot(2, 1, 1)
plt.plot(datetimes, tajimi_max_days['temperature'], color="red")
plt.subplot(2, 1, 2)
plt.plot(datetimes, nagoya_max_days['wind'], color="blue")
赤が気温、青が風速

気温と風速に関しては三日間を通してなんとなく連動していそうに見えます。

このデータでは風向きを考慮しておらず、南から吹く風も北から吹く風も同じ風として扱ってしまっているので、次に風向きを考慮した気温への影響を考えてみます。

先ほどのデータでは北北西や南南東などの16分類された方角のデータが存在します。

tajimi_max_days['wind_direction'].value_counts()

方角の影響をより強調するために、この風向きを「東西南北」の4分類に変換します。

def separated_directions(day_df):
    columns = ['wind_ne', 'wind_se', 'wind_sw', 'wind_nw']
    directions_df = pd.DataFrame(columns=columns, index=day_df.index)
    
    for k, row in day_df.iterrows():
        direction = row['wind_direction']
        direction_df = pd.DataFrame([[0, 0, 0, 0]],
                                columns = columns,
                                index = [k])
        # '北北東', '北東', '東北東', '東' は'北東(wind_ne)'としてまとめる。
        if direction in {1, 2, 3, 4}:
            direction_df['wind_ne'] = row['wind']
        # '東南東', '南東', '南南東', '南' は'南東(wind_se)'としてまとめる。
        elif direction in {5, 6, 7, 8}:
            direction_df['wind_se'] = row['wind']
        # '南南西', '南西', '西南西', '西' は'南西(wind_sw)'としてまとめる。
        elif direction in {9, 10, 11, 12}:
            direction_df['wind_sw'] = row['wind']
        # '西北西', '北西', '北北西', '北' は'北西(wind_nw)'としてまとめる。
        elif direction in {13, 14, 15, 16}:
            direction_df['wind_nw'] = row['wind']

        directions_df.update(direction_df)
    return directions_df

tajimi_directions_df = separated_directions(tajimi_max_days)
tajimi_directions_df.head()

データ量が多いため時間がかかりますので、少々お待ちください。

重回帰分析を用いて、各風向きが気温にどの程度影響しているのかを分析してみたいと思います。

重回帰分析とはざっくり説明すると、いくつかの説明変数(ここでは「東西南北それぞれの風速」)から目的変数(ここでは気温)を予測するモデルを作り、それぞれの説明変数がどの程度目的変数に影響を与えているかを数学的に記述することができる手法です。

詳細な説明は以下のリンクなどを参考にしてください。

参考)scikit-learn で線形回帰 (単回帰分析・重回帰分析)

from sklearn import linear_model
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
model = linear_model.LinearRegression()

# 説明変数に "風向きと強さ(四分類)" を利用
X = scaler.fit_transform(tajimi_directions_df)
# 目的変数は最高気温日前後の多治見市の気温
y = tajimi_max_days['temperature']
# データフレームの各列を正規化
# X = X.apply(lambda x: (x - np.mean(x)) / (np.max(x) - np.min(x)))
 
# 予測モデルを作成
model.fit(X, y)
 
# 偏回帰係数
print(pd.DataFrame({"Name":tajimi_directions_df.columns,
                    "Coefficients":np.abs(model.coef_)}).sort_values(by='Coefficients') )
 
# 切片 (誤差)
print(model.intercept_)

この結果をみると、南西からの風が気温に与える影響が最も大きく、ついで北西からの風の影響が強いということが読み取れます。この二つは他の風向きとは突出して影響が大きそうですね。

このことから「主に西から吹く風と多治見市の気温はなんらかしらの相関関係にある」ということは言えそうです。

最後に、気温と南西から吹く風、北西から吹く風をグラフにして、それぞれの傾向をみてみようと思います。

hours = tajimi_directions_df.index
plt.figure(figsize=(50, 20))

normalized_temperature = tajimi_max_days['temperature'] / tajimi_max_days['temperature'].mean()

plt.plot(hours, tajimi_max_days['temperature'], color="red")
plt.plot(hours, tajimi_directions_df['wind_sw'], color="green")
plt.plot(hours, tajimi_directions_df['wind_nw'], color="blue")

単純に風速全てをグラフに図字していた時よりも気温と風との関係が連動しているようにみえます。

4.フェーン現象の影響の考察-東海地方の標高データを確認する-

多治見市に西方から吹く風が多治見市の気温と関係がありそうなことがわかりました。

では、実際にフェーン現象が起きるような山が西側にあるのか、衛星データを使って確認してみたいと思います。Tellusで取得できるASTER GDEM 2.0の標高データを使うと、標高の変化を可視化することができます。

詳しくはASTER GDEM 2.0について解説した下記の記事を参考にしてください。

では、ASTER GDEM2.0のデータを取得する関数を定義していきます。

def get_tile_bbox(zoom, topleft_x, topleft_y, size_x=1, size_y=1):
    """
    タイル座標からバウンダリボックスを取得
    https://tools.ietf.org/html/rfc7946#section-5
    """
    def num2deg(xtile, ytile, zoom):
        # https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Python
        n = 2.0 ** zoom
        lon_deg = xtile / n * 360.0 - 180.0
        lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
        lat_deg = math.degrees(lat_rad)
        return (lon_deg, lat_deg)
    
    right_top = num2deg(topleft_x + size_x , topleft_y, zoom)
    left_bottom = num2deg(topleft_x, topleft_y + size_y, zoom)
    return (left_bottom[0], left_bottom[1], right_top[0], right_top[1])

def calc_height_chiriin_style(R, G, B, u=100):
    """
    標高タイルのRGB値から標高を計算する
    """
    hyoko = int(R*256*256 + G * 256 + B)
    if hyoko == 8388608:
        raise ValueError('N/A')
    if hyoko > 8388608:
        hyoko = (hyoko - 16777216)/u
    if hyoko < 8388608:
        hyoko = hyoko/u
    return hyoko

def plot_height(tile, index, direction, z, x, y, xtile_size=1, ytile_size=1, u=1):
    """
    高度のグラフをプロットする

    Parameters
    ----------
    tile : ndarray 
        標高タイル
    bbox : object 
        標高タイルのバウンディングボックス 
    index : number 
        走査するピクセルのインデックス 
    direction : number 
        走査方向(0で上から下、1で左から右)
    zoom : number 
        ズーム率 
    xtile : number 
        座標X 
    ytile : number 
        座標Y
    xtile_size : number 
        X方向のタイル数 
    ytile_size : number  
        Y方向のタイル数
    u : number 
        標高分解能[m](デフォルト 1.0[m])
    """
    bbox = get_tile_bbox(z, x, y, xtile_size, ytile_size) 
    width = abs(bbox[2] - bbox[0])
    height = abs(bbox[3] - bbox[1])
    if direction == 0: 
        line = tile[:,index]
        per_deg = -1 * height/tile.shape[0]
        fixed_deg = width/tile.shape[1] * index + bbox[0]
        deg = bbox[3]
        title = 'height at {} degrees longitude'.format(fixed_deg)
    else:
        line = tile[index,:]
        per_deg = width/tile.shape[1]
        fixed_deg = -1 * height/tile.shape[0] * index + bbox[3]
        deg = bbox[0]
        title = 'height at {} degrees latitude'.format(fixed_deg)
        
    heights = []
    heights_err = []
    degrees = []
    for k in range(len(line)):
        R = line[k,0]
        G = line[k,1]
        B = line[k,2]
        try:
            heights.append(calc_height_chiriin_style(R, G, B, u))
        except ValueError as e:
            heights.append(0)
            heights_err.append((i,j))
        degrees.append(deg)
        deg += per_deg

    fig, ax= plt.subplots(figsize=(8, 4)) 
    plt.plot(degrees, heights)
    plt.title(title)
    ax.text(0.01, 0.95, 'Errors: {}'.format(len(heights_err)), transform=ax.transAxes)
    plt.show()

多治見市の位置をあらためて確認してみます。下記の画像のうち、右矢印のあたりの標高差を可視化してみましょう。

上記の位置関係から、z=8, x=225, y = 101のタイル領域のうち多治見市は縦に10等分したうちの2番目あたりの高さに位置していることがわかります。ここでは500pxを10等分した50pxの位置の標高を横方向に可視化してみます。

plot_height(gdem_img, 50, 1, z, x, y)

下記のようなグラフが表示されたかと思います。

ほぼ海抜0m付近の長屋の西側に800mほどの高さの山が’あることがわかります。

つまり、多治見市の西側には多治見市の海抜よりも高い山が2つあるということ。

これらの山を超える際にさらに温度が温められた風が、多治見市の暑さの要因となっているかもしれません。

まとめ

岐阜県多治見市がなぜ暑いのかということをAMeDASのデータを用いて分析してみました。

まず、ヒートアイランド現象という観点では、「都市部は緑地の多い郊外よりも暑い」「多治見市よりも都市化が進んでいる名古屋市では、平均気温は多治見市よりも高い」ということが確認できたため、多治見市の暑さの理由に強い影響は与えてないのではないかと考えられます。

一方で、「瞬間的な最高気温では多治見市の方が高くなる傾向にある」ということが確認でき、その背景には、西風が山脈を超える際に温度が高くなるというフェーン現象の影響があるのだろうということが、多治見市の風向きと気温の傾向分析から読み取れました。

今回は風向きと風速を使って気温との関係を分析しましたが、多治見市の気温が高くなるのに他の要因が影響していることも考えられます。例えば、都市部、平野部、盆地、山間部などといった地形による気温の変化率の傾向を調べてみても面白いかもしれません。多治見市は盆地で熱が溜まりやすい土地という考察もいたるところで見かけました。

また、今回は東海エリアの中でも多治見観測所と名古屋観測所の2地点のみを対象に分析しましたが、より広域的な西日本全体や北陸から吹く偏西風の影響などといった観点で分析してみても興味深い結果が得られそうです。

ぜひ本記事を参考に気象現象についての理解を深めていただけたらと思います。

「Tellus」で衛星データを触ってみよう!

日本発のオープン&フリーなデータプラットフォーム「Tellus」で、まずは衛星データを見て、触ってみませんか?

Tellusの利用登録はこちらから