エクセルではできない?PythonでグラフをGIFアニメーション化してみた

色鉛筆の折れ線グラフ

 

別記事「統計学的に「令和婚」はあったのか?」では、2000年から2019年の婚姻数のデータとt検定を用いて、統計学的に令和婚があったかを検証した結果を紹介しました。

 

そして、その記事の中で、月別婚姻数の推移を折れ線グラフで表現したグラフを掲載しました。

 

月別婚姻数アニメーションなしカラー

 

さて、このグラフを見てどのような印象をお持ちになりましたか?

 

 

まず、エクセルで作ったグラフとは様子が異なることに気づくと思います。そして、多彩な色で線が引かれていることから、カラフルなグラフという印象を持つかもしれません。

しかしながら、逆に言えば、パッと見で、それぞれの線(月ごと)に、どのような傾向があるのか(たとえば、婚姻数が低調に見える、あの線は何月なのか?)が、直観的に分かりにくいグラフであるともいえます。

 

ということで、今回の記事では

  • matplotlibを用いたグラフ表現力の幅を広げたい
  • グラフをアニメーション化させたい

 

という人に向けて、Pythonのmatplotlibを用いたグラフのGIFアニメーション化の方法について、実際のPythonコードも交えて紹介していきます。

 

エクセルではできない?PythonでグラフをGIFアニメーション化してみた

 

キラキラしたラインの背景

 

月別婚姻数のグラフをGIFアニメーション化してみる

 

本記事のゴールは、次のGIFアニメーションを生成することです。

 

月別婚姻数アニメーション

このGIFアニメーションは、1947年から2019年までの月別婚姻数のデータを用いた折れ線グラフを、月別にハイライトさせています。

※もし、GIFアニメーションが再生しない場合は、ブラウザ上で「新しいタブで画像を開く」「画像を保存する」などを試してみてください

 

グラフ描画に今回用いた婚姻数データは、e-stat(平成30年 人口動態統計)より入手が可能です。

 

① matplotlibでの折れ線グラフ描画方法

 

今回のゴールのGIFアニメーションを生成する前に、matplotlibを用いた折れ線グラフの基本的な描画方法を確認していきます。

 

はじめに、グラフとして描画させたい、婚姻数データのcsvデータをpandasで読み込みます。

import pandas as pd
df = pd.read_csv("婚姻数.csv", encoding="shift-jis")
df.tail()

 

ここで読み込んだ次のようなデータとなっており、行を「西暦」、列に「月毎の婚姻数」を表現したデータとなっていることを確認できます。

婚姻数CSV

e-statからダウンロードしたcsvに前処理をした都合、列数がおかしなことになっていますが、そこは無視してください。

 

次に、読み込んだcsvデータでグラフを描画させます。

# グラフ描画のためのライブラリの呼び出し
import matplotlib.pyplot as plt
x = df["year"]

# グラフの作成
plt.figure(figsize=(16,4)) # グラフサイズを1600x400に指定(デフォルトは640x480)

# X軸の指定
x = df["year"]

# 1月~12月の月別婚姻数の描画
for i in range(1,13): # 1から12までを繰り返す
    month = '{}月'.format(i) # 1月から12月の文字列を用意する
    plt.plot(x, df[month]) # 折れ線グラフを描画する
    
# グラフの軸ラベル等の設定
plt.title("月別婚姻数 (1947年~2019年)",size=16) 
plt.xlabel("年",size=14) 
plt.ylabel("婚姻数",size=14) 
plt.xticks(x[::], rotation=90, size='small')# 3つおきにラベルを表示する。
plt.legend(loc='upper left') #凡例表示
plt.grid(True)

# グラフの表示
plt.show()

 

コメント部を除き、たった14行のコードで、次のグラフを出力することができます。

月別婚姻数アニメーションなしカラー

 

この基本的なグラフ描画におけるポイントは次の通りです。

  • 12行目~14行目:for文を用いて、1月から12月のグラフを繰り返し描画させる。
  • 13行目:X軸の変数となる「〇月」を、for文の変数とformat文で生成させる。
  • 20行目:X軸の西暦のラベルを全て表示させると文字の重なりが発生するため、間引いて表示させる。
  • 20行目:X軸の西暦のラベルを横表示で表示させると文字の重なりが発生するため、縦表示で表示させる。

 

 

では、次にこのグラフのGIFアニメーション化をやっていきます。

 

② 月別婚姻数グラフのGIFアニメーション作成方法

 

月別婚姻数のグラフをGIFアニメーション形式で出力させるための方法を紹介していきます。

アニメーション化させる目的は、情報をより伝わりやすい形で表現とするためです。

 

今回は、月別の各折れ線グラフを強調させるような、アニメーションをつくっていきます。

 

コードは次の通りです。

# グラフ描画のためのライブラリを呼び出す
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import Image

# グラフの作成
fig, ax = plt.subplots(figsize=(16,4))

# X軸の指定
x = df["year"]

# 1月~12月の月別婚姻数の描画
for i in range(1,13): # 1から12までを繰り返す
    month = '{}月'.format(i) # 1月から12月の文字列を用意する
    ax.plot(x, df[month], color="gray", zorder=1,linestyle="dashed") # 折れ線グラフを描画する
    
# グラフの軸ラベル等の設定
plt.title("月別婚姻数 (1947年~2019年)",size=16) 
plt.ylabel("婚姻数",size=14) 
plt.xticks(x[::], rotation=90, size='small') # 3つおきにラベルを表示する。        
plt.xlabel("年",size=14) 
plt.grid(True)

# GIFアニメ格納用の空のリストの作成
artists = []

# 1月~12月の月別婚姻数のアニメ用グラフの描画
for j in range(1,13): # 1から12までを繰り返す
    month = '{}月'.format(j) # 1月から12月の文字列を用意する
    my_line, = ax.plot(x, df[month], color="red",zorder=2, linewidth = 4.0) # 折れ線グラフを描画する
    my_text = ax.text(x[0], df[month][0], month, color="red", fontsize=16, ha='right') # 折れ線グラフに添える月情報を描画する
    artists.append([my_line, my_text, my_xlabel]) # リストにハイライトさせた月毎のグラフを加えていく

# GIFアニメの保存
ani = animation.ArtistAnimation(fig, artists, interval=500) # インターバル500ms
ani.save('./konin_animation.gif', writer='pillow')
plt.close()

# 保存したGIFアニメの表示
Image('./konin_animation.gif')

 

ここでのポイントは次の通りです。

  • 12行目~22行目:アニメーションのベース(背景)となるグラフを描画させる。
  • 15行目:ベース(背景)となるグラフとなるため、描画する折れ線グラフは、灰色×点線で描画させる。
  • 25行目:GIFアニメーション用の1枚1枚のaxes(グラフの要素)を格納する空のリストを用意する。
  • 27行目~32行目:for文を用いて、アニメーション用のグラフを繰り返し描画させる。
  • 30行目:注目する月の折れ線グラフをハイライトさせるため、赤線×太い線で描画を行う。
  • 31行目:アニメーションで表示する「〇月」情報を表示するためにテキストを折れ線グラフの左端に描画する。
  • 35行目~40行目:生成したGIFアニメを一度保存し、その画像を読み出し表示させる(plot.showでは表示不可能)
  • 35行目~40行目:GIFアニメは500msec(0.5秒)毎に切り替える(少し早いかもです)

 

それぞれどういった処理を行っているのは、コード中のコメントも参照してみてください。

 

基本的なGIFアニメーションからTryしたい場合は、ググってみよう。

 

今回のコードで、グラフのGIFアニメーションを生成することができました。ただし、今回のコードは、著者がやってみたいと思ったグラフのGIFアニメーションを実現させたコードであることから、やや応用的なコード例と言えます。

今回の記事で、PythonによるGIFアニメにより興味を持った方は、「matplotlib GIFアニメ」などで検索していただくと、もっと基本的なGIFアニメーションの紹介記事があるので、そちらも参照してみてください。

 

なお、今回のグラフのGIFアニメーションを生成するために、グラフ描画を2回に分けて行っております。ここは、著者が今回のグラフ作成で、最もはまった(苦戦した)ポイントでもありました。ただ、その内容は少し込み入った話となりますので、また別の記事で紹介したいと思います。

 

PythonのグラフGIFアニメーション化でグラフを2回描画させた2つの理由

 

まとめ

 

今回の記事では、PythonでグラフのGIFアニメーション化について、実際のPythonコードも交えて紹介していきました。

matplotlibのanimation機能を用いることで、グラフのGIFアニメーション化は可能となります。

 

今回の例では、婚姻数の推移の各月の違いをGIFアニメーションで表現しましたが、matplotlibでGIFアニメーションできるということは、

  • 回帰分析による将来予想において、特定のパラメタ(説明変数)を変化させた場合の、予想値の変化の様をアニメ化させる
  • クラスタリング分析において、特定のパラメタ(説明変数)を変化させた場合の、分類の変わり様をアニメ化させる

 

などにも、応用が可能と言えます。

 

みなさんはGIFアニメーションでどのようなグラフ作成をしてみたいですか?

 

最後に、

  • 婚姻数が低調に見える(1980年で最も最低婚姻数を記録している)あの線は何月なのか?
  • 2019年に婚姻数がはね伸びているあの線は何月なのか?

 

の答えは分かりましたでしょうか?

ぜひ、次のGIFアニメーションで確認してみてくださいませ。

 

婚姻数推移月別アニメ2

 

じゃあ

 

 

当ブログを運営している「パラレルキャリア研究会」は、30代~50代ビジネスパーソンがパラレルキャリアの開発を続けていくことを目的とし活動を行っております。

そして「パラレルキャリア研究会」には、「統計学」「データエンジニアリング」「コンサルティング」などデータサイエンスの各テーマに興味がある&学習しているメンバーが業種・業界・年齢を問わず集まっております。

そのため「これからデータサイエンスを学んでいきたい × 学習仲間も増やしていきたい」と考えている方は、ぜひ一度「パラレルキャリア研究会」の活動をのぞいてみてください。

 

関連記事

統計学的に「令和婚」はあったのか?

エクセルより便利?Pythonで散布図の特異なデータを色分け表示させる方法

PythonのグラフGIFアニメーション化でグラフを2回描画させた2つの理由

[article-banner-2]

ABOUTこの記事をかいた人

パラレルキャリア研究会創設メンバー 岩手県出身。東北大学工学部卒、同大学院工学研究科修了。半導体メーカーに入社後、エンジニアとして半導体製品の企画・開発に従事。30代後半に軸ずらし転職でキャリアをシフト。本業の傍ら独学でPython&統計学を学習中。1児のパパ。趣味は日本酒、ロードバイク。中小企業診断士、SAKE DIPLOMA。