見出し画像

便利ライブラリ matplotlib② グラフをきれいに!

matplotlib①では基本的な使い方について書きましたが、味気ないグラフでした。今回はそんなグラフの見やすく変える設定について書いていきます。
以下、前回のコードです。作業ディレクトリ内にVScodeの使い方で作成した「Aichi.xlsx」を保存した状態でコードを書いています。

import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_excel('Aichi.xlsx')
df['Date'] = pd.to_datetime(df['Date'])
df = df.query("'2021-01-01' <= Date < '2021-02-01'")
x = df['Date']
y = df['Aichi']

fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()

グラフの見栄えを良くしよう!

サイズ変更

サイズ変更は、plt.subplots()の引数にfigsize=(横インチ, 縦インチ)を渡すことで変更できます。

fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y)
plt.show()

軸の表示設定

大きさは変わりましたが、x軸の表記が重なって見にくくなっています。重ならないようにするため、回転する角度を設定します(①)。
補助線があった方が見やすい場合があります。ax.grid()で補助線について設定します。引数に、color(色)、linestyle(スタイル)、linewidth(太さ)を指定できます。linestyleには、’solid'や'dotted'、'dashed'などの線のスタイルを指定します(②)。
グラフのタイトル(③)、x軸ラベル(④)、y軸ラベル(⑤)を設定します。
軸のレンジは自動で設定されますが、軸のレンジを揃えた方が別のグラフと比較し易くなります。もちろん変更することは可能です。例では、y軸が1から6ぐらいまでになっているので、0から8の範囲に設定します(⑥)。

fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y)
fig.autofmt_xdate(rotation=30)  #①
ax.grid(color='gray', linestyle='dotted', linewidth=1)  #②
ax.set_title('Aichi', fontsize=15)  #③
ax.set_xlabel('Date', fontsize=13)  #④
ax.set_ylabel('Number of COVID-19 positive cases (/0.1Mil)', fontsize=13)  #⑤
ax.set_ylim(0, 8)  #⑥
plt.show()

だいぶ見やすくなりました!
もっと細かくいろいろ設定できるので、公式ドキュメント等を見ながら試してみてください。

Subplots

前回、台紙の上にグラフが描かれているイメージについて書きました。その台紙は分割することができ、グラフを並べることができます。
せっかくなので、東京、大阪、愛知のデータを作成し比較できるように並べてみましょう。

データの準備

「Aichi.xlsx」同様に「Tokyo.xlsx」と「Osaka.xlsx」のデータも作業ディレクトリにコピーしておきます。
どのファイルも同じ構成のデータ(年月日が入ったDate列と陽性者数がはいった列)なので、期間抽出などのデータ整形は関数化するとコードがスッキリします。

def dataTrimmer(file_path):
    df = pd.read_excel(file_path)
    df['Date'] = pd.to_datetime(df['Date'])
    df.rename(columns={f'{df.columns[1]}': 'num'}, inplace=True)
    df = df.query("'2021-01-01' <= Date < '2021-02-01'")
    return df

df_tokyo = dataTrimmer('Tokyo.xlsx')
df_osaka = dataTrimmer('Osaka.xlsx')
df_aichi = dataTrimmer('Aichi.xlsx')

dataTrimer()という関数を定義しました。引数にExcelファイルのパスを渡せば、整形したDataFrameが返ってきます。Excelファイルが同一ディレクトリ内にあればファイル名(○○.xlsx)だけで良いですし、絶対パスを使用して別のディレクトリにあるファイルを指定することも出来ます。

1つのグラフ

まずは、1つのグラフに3つのデータを重ねて表示します。plt.legend()は凡例を表示させるコードです。

fig, ax = plt.subplots(figsize=(10, 8))
ax.plot(df_tokyo['Date'], df_tokyo['num'], label='Tokyo')
ax.plot(df_osaka['Date'], df_osaka['num'], label='Osaka')
ax.plot(df_aichi['Date'], df_aichi['num'], label='Aichi')

fig.autofmt_xdate(rotation=30)
ax.grid(color='gray', linestyle='dotted', linewidth=1)
ax.set_title('Number of COVID-19 positive cases (/0.1Mil)', fontsize=15)
ax.set_xlabel('Date', fontsize=13)
ax.set_ylim(0, 19)
plt.legend(fontsize=13)
plt.show()

Subplotsでグラフを並べて表示

複数のグラフを作成する場合、plt.subplots(行数, 列数)というように配置するグラフに合わせて区画を作成します。
今回は1行3列(横に3つ並べる)なので、ax = plt.subplots(1, 3)とします。
次に、どの区画にどのグラフを表示するか指定します。axに3区画準備されているので、それぞれax[0]、ax[1]、ax[2]というようにインデックス番号で区別して表記します。

fig, ax = plt.subplots(1, 3, figsize=(20, 8))  # 1x3の区画を準備
ax[0].plot(df_tokyo['Date'], df_tokyo['num'])
ax[1].plot(df_osaka['Date'], df_osaka['num'])
ax[2].plot(df_aichi['Date'], df_aichi['num'])
fig.autofmt_xdate(rotation=30)

3つ並べることができました。でも、せっかく並べたのにy軸がバラバラで比較しにくいですね。先程と同様に、軸の設定を行い見やすくしましょう。ax[0]、ax[1]、ax[2]のそれぞれに対し設定を行いますが、今回は3つとも同じ設定を行った方が見やすいので、for文を用いてループ処理します。

fig, ax = plt.subplots(1, 3, figsize=(20, 8))
ax[0].plot(df_tokyo['Date'], df_tokyo['num'])
ax[1].plot(df_osaka['Date'], df_osaka['num'])
ax[2].plot(df_aichi['Date'], df_aichi['num'])
fig.autofmt_xdate(rotation=30)

prefs=['Tokyo', 'Osaka', 'Aichi']
for i in range(len(prefs)):
    ax[i].grid(color='gray', linestyle='dotted', linewidth=1)
    ax[i].set_title(f'{prefs[i]}', fontsize=15)
    ax[i].set_xlabel('Date', fontsize=13)
    ax[i].set_ylim(0, 19)
plt.show()

体裁を整えたことで格段に見やすく、そして比較しやすくなりました。

今回は1x3の区画割りだったので、axはリストのようにインデックス番号で指定することができました。2x3のように複数行ある場合は、ax[0, 0]、ax[0, 1]… ax[1, 2]というようにax[行, 列]で指定する必要があります。

fig, ax = plt.subplots(2, 3, figsize=(20, 8))
fig.suptitle('Number of COVID-19 positive cases (/0.1Mil)', fontsize=17)
# 1段目のグラフ
ax[0, 0].plot(df_tokyo['Date'], df_tokyo['num'])
ax[0, 1].plot(df_osaka['Date'], df_osaka['num'])
ax[0, 2].plot(df_aichi['Date'], df_aichi['num'])
fig.autofmt_xdate(rotation=30)

prefs=['Tokyo', 'Osaka', 'Aichi']
for i in range(len(prefs)):
    ax[0, i].grid(color='gray', linestyle='dotted', linewidth=1)
    ax[0, i].set_title(f'{prefs[i]}', fontsize=15)
    ax[0, i].set_ylim(0, 19)

# 2段目のグラフ
ax[1, 0].bar(df_tokyo['Date'], df_tokyo['num'])
ax[1, 1].bar(df_osaka['Date'], df_osaka['num'])
ax[1, 2].bar(df_aichi['Date'], df_aichi['num'])
for i in range(len(prefs)):
    ax[1, i].plot(df_tokyo['Date'], df_tokyo['num'] + df_osaka['num'] + df_aichi['num'], 
                  label='Total', color='red', linestyle='dashed')  # 東京・大阪・愛知の合算値
    ax[1, i].grid(color='gray', linestyle='dotted', linewidth=1)
    ax[1, i].set_xlabel('Date', fontsize=13)
    ax[1, i].set_ylim(0, 35)

plt.legend()
plt.show()

plt.bar()で棒グラフが作成できます。引数はplt.plot()と同様でxとyを指定するだけです。
論文に載ってそうなグラフにすることができました☆

グラフの保存

画像ファイルとして作成したグラフを保存できます。イメージ的にはグラフが貼り付けてある台紙ごと保存されるので、figに対して.savefig()メソッドで保存できます。引数には保存するファイル名(ディレクトリ)を指定します。

fig.savefig('sample.png')

この記事が気に入ったらサポートをしてみませんか?