気象過去データの利用４（東京オリンピック期間の天気の気持ち）

気象庁が、2020年3月末まで、気象過去データを無償で提供しています。
(参考) 気象過去データの利用環境
https://www.data.jma.go.jp/developer/past_data/index.html

基本的な気象データは、「利用目的・対象を問わず、どなたでもご利用頂けます。」とのことなので、気象データを使って何か行っていきます。

気象庁の「過去の気象データ・ダウンロード」ページからもダウンロードできますが、まとめて一括してダウンロードできるため非常に便利です。
利用可能なデータは、以下の掲載されています。
https://www.data.jma.go.jp/developer/past_data/data_list_20200114.pdf
もうすぐ期限ですので、必要な方は早めのダウンロードを

今回は、東京オリンピック期間の天気を文字で表現してみます。
文字の表示には、WordCloud(1.6.0)を利用します。

# データダウンロード
「気象過去データの利用２（東京オリンピック期間の最高気温変遷）」と同様に「地上気象観測」－「時・日別値」を利用します。
ファイルの形式については、以下を確認してください。
http://data.wxbc.jp/basic_data/kansoku/surface/format_surface.pdf

surfaceフォルダにファイルをダウンロードします。約2GBの容量があるため時間がかかります。

```python
import os
import urllib.request

# 地上気象観測　時・日別値ファイルダウンロード
url    = 'http://data.wxbc.jp/basic_data/kansoku/surface/hourly_daily_1872-2019_v191121.tar'
folder = 'surface'
path   = 'surface/hourly_daily_1872-2019_v191121.tar'
# フォルダ作成
os.makedirs(folder, exist_ok=True)
if not os.path.exists(path):
    # ダウンロード
    urllib.request.urlretrieve(url, path)
```

ファイルの詳細は、「気象過去データの利用２（東京オリンピック期間の最高気温変遷）」を参照してください。

# 天気データの読み込み
天気データは、天気概況として、「昼間」、「夜間」のデータが格納されています。
今回は、「昼間」のデータを利用します。
天気概況は、最大４つの天気と接続詞から構成されます。例えば、一日中晴れの場合は、「晴」、複数の天気で構成される例としては、「曇時々晴」、「曇一時雨後晴」「曇時々晴一時雨、雷を伴う」

|コード|接続詞|
|-----:|:-----|
|0|データなし|
|1|空白|
|2|一時|
|3|時々|
|4|後|
|5|後一時|
|6|後時々|
|7|を伴う（、○○を伴う）|

|コード|天気|コード|天気|コード|天気|
|----:|:---|----:|:---|----:|:---|
| 0|天気なし|10|みぞれ|20|大風|
| 1|快晴|11|雪|21|雷|
| 2|晴|12|大雪|22|あられ|
| 3|薄曇|13|暴風雪|23|ひょう|
| 4|曇|14|ふぶき|24|大風・雷|
| 5|霧|15|地ふぶき|25|雷・あられ|
| 6|霧雨|16|予備|26|雷・ひょう|
| 7|雨|17|予備|27|雷・霧|
| 8|大雨|18|予備|28|降水なし|
| 9|暴風雨|19|予備|29|晴れ間あり|
|||||30|予備|
|||||31|×|

「大雨」は、30mm以上の降雨があった場合に用いられます。詳細は、以下のサイトを参照してください。
http://www.data.jma.go.jp/obd/stats/data/mdrr/man/gaikyo.html

変換用のリストを用意します。

```python
conjunction = ['データなし', '空白', '一時', '時々', '後', '後一時', '後時々', '、']
conjunction7 = 'を伴う'
weather = ['天気なし', '快晴', '晴', '薄曇', '曇', '霧', '霧雨', '雨', '大雨', '暴風雨',
           'みぞれ', '雪', '大雪', '暴風雪', 'ふぶき', '地ふぶき', '予備', '予備', '予備', '予備',
           '大風', '雷', 'あられ', 'ひょう', '大風・雷', '雷・あられ', '雷・ひょう', '雷・霧', '降水なし', '晴れ間あり',
           '予備', '×']
```

接続詞は、一般的に天気の前につけますが、「を伴う」の場合は、「、○○を伴う」のように天気(○○の部分)が中間に入ります。

pandasのデータフレームにデータを読み込みます。
各日の1500バイト目から天気概況が格納されています。数値を文字に変換しながら読み込みます。
後で、WordCloudで表示するため、各単語の間に空白を入れます。WordCloudは、単語の分解をしてくれません。あらかじめ、単語に分解して渡す必要があります。

```python
# データ格納用データフレーム作成
import pandas as pd

tokyo_df = pd.DataFrame()
```

```python
# 天気概況取得
import tarfile

# 地点設定=東京
p_no = '662'

# tarファイルに含まれるファイルを取得
with tarfile.open(path, 'r') as tf:
    for tarinfo in tf:
        if tarinfo.isfile():
            # tar.gzファイルに含まれるファイルを取得
            with tarfile.open(fileobj=tf.extractfile(tarinfo), mode='r') as tf2:
                for tarinfo2 in tf2:
                    if tarinfo2.isfile():
                        # 地点が一致するファイルのみ読み込み
                        if tarinfo2.name[-3:] == p_no:
                            print(tarinfo2.name)
                            # ファイルをopen
                            with tf2.extractfile(tarinfo2) as tf3:
                                lines = tf3.readlines()
                                for line in lines:
                                    # データが含まれないファイルは無視
                                    if line[0:3] == b'   ':
                                        continue
                                    # 年
                                    year = line[14:18].decode()
                                    # 月日
                                    date = line[18:22].decode().replace(' ', '0')
                                    # 天気概況を取得
                                    conditions = ''
                                    p = 1500
                                    #
                                    for i in range(4):
                                        # 接続詞
                                        c = int(line[p:p+1])
                                        c_rmk = int(line[p+1:p+2])
                                        if c_rmk == 8:
                                            conditions += conjunction[c] + ' '
                                        # 天気
                                        w = int(line[p+2:p+4])
                                        w_rmk = int(line[p+4:p+5])
                                        if w_rmk == 8:
                                            conditions += weather[w] + ' '
                                            if c == 7: # 〇〇を伴う場合は、後ろにつける。
                                                conditions += conjunction7 + ' '
                                        p += 5

                                    # データ格納
                                    tokyo_df.loc[year, date] = conditions
```

データを確認します。

```python
# データ確認
tokyo_df
```

古い時代には天気の情報が入っていません。1989年以降が今の形式となったようですので、1989年以降のデータを取り出します。日付は、オリンピック期間とします。

```python
tokyo_olympic_df = tokyo_df.loc['1989':'2019','0724':'0809']
tokyo_olympic_df
```
正しく天気が入っていますね。

# WordCloudによる表示
WordCloudを用いて天気を表示してみましょう。天気概況に使用されている単語の出現数に応じて文字の大きさが変わります。
一日中「晴」でも、「曇一時晴」でも「晴」は同じ1つてとしてカウントされるため、正確に天気を反映できていないかもしれませんが、大まかな状況は把握できるはずです。
また、接続詞も入っていますが、天気の変わりぐらいを表すためそのままにしておきます。

まずは、年ごとにオリンピック期間の天気を確認してみます。
年ごとに、天気概況の文字列を結合し、WordCloudに渡します。
注意点です。
・日本語を表示するためにフォント(font_path)を指定します。私の環境はWinodwsのためMSゴシックを指定しました。各自環境に合わせて適切なフォントに変更してください。
・既定値では、1文字の単語は表示されません。regexpで正規表現を指定し表示させます。

```python
import matplotlib.pyplot as plt
from wordcloud import WordCloud
```

```python
# 年ごとに表示
i = 1
plt.figure(figsize=(16, 33))
for row in tokyo_olympic_df.index:
    text = ''
    for column in tokyo_olympic_df.columns:
        text += tokyo_olympic_df.loc[row, column]
    # WordCloudによる文字画像作成
    wordcloud = WordCloud(colormap='jet', font_path="msgothic.ttc", regexp="\w+").generate(text)
    plt.subplot(11,3,i)
    plt.imshow(wordcloud)
    plt.title(row)
    plt.axis("off")
    i += 1
plt.show()
```

結果です。本当は、晴や雨など天気に応じて文字色を変更できればよいのですが、文字色はランダムに選択されるようです。
年によって若干ばらつきがありますが、おおむね晴や曇が多いですね。
![WordCloud_year.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212365/9bec98fa-68ec-e7a6-dcf2-3b332e5d7882.png)

日付ごとです。

```python
# 日付ごとに表示
i = 1
plt.figure(figsize=(16, 18))
for column in tokyo_olympic_df.columns:
    text = ''
    for row in tokyo_olympic_df.index:
        text += tokyo_olympic_df.loc[row, column]
    # WordCloudによる文字画像作成
    wordcloud = WordCloud(colormap='jet', font_path="msgothic.ttc", regexp="\w+").generate(text)
    plt.subplot(6,3,i)
    plt.imshow(wordcloud)
    plt.title(column)
    plt.axis("off")
    i += 1
plt.show()
```

真夏のため、晴が多いですね。
![WordCloud_date.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212365/9629d3c4-2cf9-d484-52f7-10035bd8058d.png)

# 天気の気持ちカレンダー
せっかくなので、天気の気持ちカレンダーを作成してみましょう。
1年分です。2019年は、途中までのデータしかないため、2018年までとします。また、うるう年の2月29日は削除しました。

```python
tokyo_365_df = tokyo_df.loc['1989':'2018']
tokyo_365_df = tokyo_365_df.drop('0229', axis=1)
tokyo_365_df
```

```python
# 日付ごとに表示
i = 1
plt.figure(figsize=(16, 40))
for column in tokyo_365_df.columns:
    text = ''
    for row in tokyo_365_df.index:
        text += tokyo_365_df.loc[row, column]
    # WordCloudによる文字画像作成
    wordcloud = WordCloud(colormap='jet', font_path="msgothic.ttc", regexp="\w+").generate(text)
    plt.subplot(37,10,i)
    plt.imshow(wordcloud)
    plt.title(column)
    plt.axis("off")
    i += 1
plt.show()
```

東京の１年分のカレンダーです。
![WordCloud_tokyo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212365/8caeaf5d-0fc6-334b-9fc9-c91fd59cdb48.png)

梅雨の時期は、雨が目立ちますね。
晴の特異日と言われている前回の東京オリンピックの開会式があった10月10日は、周辺の日付に比べて雨が少ないように見えます。晴の特異日と言えると思います。

地点は、`p_no = '662'`の地点番号を変更することで対応できます。地元の地点のカレンダーを作成した場合は、地点番号を変更してください。地点番号は、地点情報履歴ファイル（smaster_201909.tar.gz）で確認できます。

札幌(412)の例です。
冬場は、雪が多いですね。

![WordCloud_sapporo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212365/a99757f6-8290-cb70-6959-6ab4ff682c23.png)

今回は、天気を文字の大きさで表してみました。数値やグラフで表す方が正確ですが、文字の大きさで表すと直感的で面白いです。

データの公開期間が2020年3月末までのため、必要な方は、早めのダウンロードをお勧めします。