🌏

東京都の月別平均気温を Climate Spiral っぽく可視化した

2023/07/18に公開

はじめに

最近暑いですね。猛暑日が続いたり、早朝から30℃超えたり、梅雨明けを待たず厳しい季節が続きます。この時期になると、地球温暖化の話がインターネットで毎年見られます。

地球温暖化の真偽は置いておくとして、以前NASAが作った Climate Spriral という可視化はよく出来ているなと感じます。

https://www.youtube.com/watch?v=jWoCXLuTIkI&ab_channel=NASAClimateChange

今回の記事では、東京都のデータを使って、似たような作図をmatplotlibで行うことを目指します。

作ったもの

先に作ったものを貼っておきます(1876年〜2022年で、大変長いGIF画像です)。

gif

作り方

データを用意して、matplotlibでアニメーションを作ります。

データ

まずはデータですが、東京都の月ごとの平均気温を使っています。

https://www.data.jma.go.jp/obd/stats/etrn/view/monthly_s3.php?prec_no=44&block_no=47662

データを詳しく見ていませんが、変な記号を取り除いたりして作成したCSVファイルがこちらです。

https://github.com/cocomoff/tokyo-temp-circular-plot/blob/main/data/tokyo.csv

処理

平均的な挙動の差分を可視化するため、CSVファイルをpandasで読み込んだ後に、次の処理をしています。

  • 月ごとの平均を全データで計算する。
  • 各月のデータを平均からの差分で表現し直す。

この処理の後で、1876年から2022年のデータをプロットします。

matplotlibを使ったプロット

YouTube動画を参考にして揃えるために

  • 時計の12時 (N側) を原点 (0°) に設定する
  • 時計回り (右回転) で月を進める (12時が1月、1時が2月、…)

という設定をしています。1876年から2022年までのプロットが重複していくため、各月のプロットを行う際に、今プロットを行った年月までのデータを灰色で薄く、今プロットしている月を赤色で濃くプロットしました。この処理を行っている部分の抜粋です。

months: List[str] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", \
                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]    

def make_gif(xvalues: List[float],  # 1月〜12月の°が繰り返し入る
             yvalues: List[float],  # 1876年1月〜2022年12月の平均気温が入る
             oname: str = "tokyo.gif",
             interval: int = 3) -> None:
    M: int = len(xvalues)
    fig, ax = plt.subplots(subplot_kw={'projection': 'polar'},
                           figsize=(6, 6), dpi=150)

    # 見た目の調整 (ここにいるのかな?)
    ax.grid(True)
    ax.set_theta_zero_location("N")
    ax.set_theta_direction(-1)
    ax.set_ylim([-5.0, 5.0])
    ax.set_xticks(np.linspace(0, 2 * np.pi, num=12, endpoint=False))
    ax.set_xticklabels(months)

    # 更新関数 (i番目の線分を作る)
    def plot(i):
        plt.cla()
        
        # 見た目の設定
        ax.grid(True)
        ax.set_theta_zero_location("N")
        ax.set_theta_direction(-1)
        ax.set_ylim([-5.0, 5.0])
        ax.set_xticks(np.linspace(0, 2 * np.pi, num=12, endpoint=False))
        ax.set_xticklabels(months)

        # タイトル (年)
        off = i // 12
        year = 1876 + off
        ax.set_title(f"Year {year}")

        # これまでのプロット (薄く) / 新しいプロット (赤色)
        prevs_xx = [xvalues[k] for k in range(i + 1)]
        prevs_yy = [yvalues[k] for k in range(i + 1)]
        if prevs_xx:
            ax.plot(prevs_xx, prevs_yy, color="k", alpha=0.2)

        if i < len(xvalues) - 1:
            xx = [xvalues[i], xvalues[i + 1]]
            yy = [yvalues[i], yvalues[i + 1]]
            ax.plot(xx, yy, color="r", alpha=0.5)

    # 保存する
    ani = animation.FuncAnimation(fig, plot, save_count=M,
                                  interval=interval, repeat=False)
    ani.save(oname)

抽出した結果

上に張った結果 (GIF画像) だと長過ぎるので、一部抜粋したものを見てみます。

画像
1900年12月
1945年12月
1990年12月
2020年12月

まとめ

なんとか涼しい季節まで頑張って生活していきましょうね。こちらの記事に使った素材のファイルなどはgithubにおいてあります。

https://github.com/cocomoff/tokyo-temp-circular-plot

Climate spiralのWikipediaページも貼っておきます。

https://en.wikipedia.org/wiki/Climate_spiral

Discussion