Python マルチインデックスの棒グラフの横軸2段表示

 Multi-Index(マルチインデックス)とは、下図のようにインデックスがOne, Twoとa, bのように複数のインデックスがあることを言います。

 本記事では、上記のようなデータセットに対して、下図右のように横軸が2段表示になるような雛形コードを載せました。参考までに、下図左はデフォルト設定でグラフ化した場合で、横軸が(One, a)のようなカッコで1行表示になっています。

■本プログラム

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
plt.rcParams['font.size'] = 14 # グラフの基本フォントサイズの設定

# サンプルのデータを作成
data = {
    'A': [1,2,3,4],
    'B': [5,6,7,8],
    'C': [9,10,11,12],
    'D': [13,14,15,16],    
}

# インデックスの階層を持つDataFrameを作成
index = pd.MultiIndex.from_tuples([
    ('One', 'a'), ('One', 'b'), 
    ('Two', 'a'), ('Two', 'b')
])
df = pd.DataFrame(data, index=index)

# データをプロット
ax = df.plot(kind='bar', figsize=(6, 4))
plt.ylabel('data')

# 各棒グラフの上に値を表示
for p in ax.patches:
    ax.annotate(str(p.get_height()), (p.get_x() + p.get_width() / 2., p.get_height()), ha='center', va='bottom')

# 現状のオブジェクト設定を取得
ax = plt.gca()

# 横軸上段のラベルを設定
ax.set_xticks(np.arange(0.5, len(df.index), 2), minor=False)
xticklabels_top = [i[0] for i in df.index[::2]]
ax.set_xticklabels(xticklabels_top, minor=False, fontsize=14, va='top', rotation=0)

# 横軸下段のラベルを設定
ax.set_xticks(np.arange(0, len(df.index), 1), minor=True)
xticklabels_bottom = [i[1] for i in df.index]
ax.set_xticklabels(xticklabels_bottom, minor=True, fontsize=14, va='bottom', rotation=0)

# 凡例の位置
ax.legend(bbox_to_anchor=(1, 1)) # 凡例の位置

# ラベルの位置を下げる
plt.setp(ax.get_xticklabels(minor=False), y=-0.05)
plt.setp(ax.get_xticklabels(minor=True), y=-0.05)

# グリッド
plt.grid(axis='y', linestyle='dotted', color='gray')

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

# 画像ファイルに保存
plt.savefig('sample.jpg', bbox_inches='tight')

以上

<広告>