inch-blog

Welcome to Inch-blog ! Home is a place where you can read mainly technical articles. LIFE is mainly about my personal life.

matplotlib を用いて複数の棒グラフを描画する

今回作成予定のグラフ

例 1

image block
print(df)
#    0  1  2
# 0  1  8  3
# 1  7  2  2
# 2  7  6  3
# 3  9  6  6
# 4  1  4  6

例 2

image block
print(df)
#       A  B  C
# 2001  6  5  1
# 2002  8  5  5
# 2003  7  4  6
# 2004  4  3  7
# 2005  8  4  2

実際のコード

例 1 のコード
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

fig = plt.figure(figsize=(6.4 * 1, 4.8))

ax = fig.add_subplot(1, 1, 1, xlabel='x', ylabel='y')

width = 0.2

df = pd.DataFrame(data=np.random.randint(1, 10, (5, 3)))

cols = df.columns
df_index = np.array(df.index)
for i, col in enumerate(cols):
    ax.bar(df_index+width*(i-len(cols)/2), df.loc[:, col], label=col, width=width, align='edge')
ax.legend()
fig.savefig('example1.png')
image block
例 2 のコード
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

fig = plt.figure(figsize=(6.4 * 1, 4.8))

ax = fig.add_subplot(1, 1, 1, xlabel='x', ylabel='y')

width = 0.2

df = pd.DataFrame(data=np.random.randint(1, 10, (5, 3)), columns=["A", "B", "C"], index=np.arange(2001, 2005 + 1, 1))

cols = df.columns
df_index = np.array(df.index)
for i, col in enumerate(cols):
    ax.bar(df_index+width*(i-len(cols)/2), df.loc[:, col], label=col, width=width, align='edge')
ax.legend()
fig.savefig('example2.png')
image block

DataFrame の Index が DatetimeIndex の場合

from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from matplotlib import dates as mdates
from matplotlib import ticker

import numpy as np
import pandas as pd

fig = plt.figure(figsize=(6.4 * 1, 4.8))

ax = fig.add_subplot(1, 1, 1, xlabel='x', ylabel='y')

width = 0.2

df = pd.DataFrame(data=np.random.randint(1, 10, (5, 3)), columns=["A", "B", "C"], index=[datetime(2020, 1, 25) + timedelta(days=i) for i in range(5)])
time = [datetime(2020, 1, 25) + timedelta(days=i) for i in range(10)]

#             A  B  C
# 2020-01-25  6  6  5
# 2020-01-26  1  8  5
# 2020-01-27  5  7  4
# 2020-01-28  6  4  3
# 2020-01-29  7  8  4

# DatetimeIndex(['2020-01-25', '2020-01-26', '2020-01-27', '2020-01-28',
#                '2020-01-29'],
#               dtype='datetime64[ns]', freq=None)

cols = df.columns
df_index = mdates.date2num(df.index)

for i, col in enumerate(cols):
    ax.bar(df_index+width*(i-len(cols)/2), df.loc[:, col], label=col, width=width, align='edge')
ax.xaxis.set_major_locator(mdates.DayLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y年%m月%d日"))
ax.xaxis.set_tick_params(rotation=90)
ax.legend()
fig.savefig('example3.png')
image block

上記コードの

df_index = mdates.date2num(df.index)

で datetime オブジェクトを Matplotlib の日付に変換することができるので変更します.

次に

ax.xaxis.set_major_locator(mdates.DayLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y年%m月%d日"))
ax.xaxis.set_tick_params(rotation=90)

で日付を表示させる間隔と表記、文字列の回転を指定すればOKです.

備考

witdh について

今回の例では 3 つの棒グラフを表示していますが,数が増えると棒グラフが重なるので

width を 0.15 にするなどして対応してください.

参考にしたサイト

https://dreamer-uma.com/python-matplotlib-bar/

https://matplotlib.org/stable/api/dates_api.html