[Matplotlib] 積み上げグラフ

積み上げグラフとは下図のように複数のデータを重ねたグラフのことで、複数要素の割合を示すために使われます。

棒グラフ

棒グラフで積み上げグラフを描画する場合は、以下の順番で行います。

  • 1つめのデータを描画
  • barのbottomオプションを使って、1つめのデータの上から2つめのデータを描画

下図は棒グラフを横に並べたパターン(default)と積み上げグラフ(stack)を比較したものです。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

# 目盛り(x方向)とランダム値(y方向)を生成
x1 = [i for i in range(20)]
y1 = [np.random.randint(0, 100) for i in range(20)]

# 2つ目のデータを作成
y2 = [np.random.randint(0, 100) for i in range(20)]

fig, ax = plt.subplots(2, sharey=True)

# 横に並べて描画
# x座標は横に並べるために位置をシフト
ax[0].bar(x1, y1, width=0.4)
ax[0].bar(np.array(x1) + 0.4, y2, width=0.4)

# y1の高さをbottomとして2つめのデータを描画
ax[1].bar(x1, y1, width=0.4)
ax[1].bar(x1, y2, bottom=y1, width=0.4)

# グラフタイトルの設定
ax[0].set_title('default')
ax[1].set_title('stack')

fig.tight_layout()

plt.show()

ヒストグラム

ヒストグラムの場合はオプションでstacked=Trueを設定することで積み上げグラフを作成できます。

# ランダムな3つのデータ群を作成
x1 = [np.random.randint(0, 100) for i in range(200)]
x2 = [np.random.randint(0, 100) for i in range(200)]

fig, ax = plt.subplots(2, sharey=True)

# 2つのデータを並べたグラフを描画
ax[0].hist([x1, x2], width=4)

# 2つのデータをstack
ax[1].hist([x1, x2], width=4, stacked=True)

# タイトルの設定
ax[0].set_title('default')
ax[1].set_title('stack')

fig.tight_layout()

plt.show()

ちなみに、bottomを設定することでも積み上げグラフを作成できます。ただ、データ数が多くなった時にコードを書くのがちょっと面倒になりますので、上のやり方のほうがよいかなと思います。

# 横に並べて描画
ax[0].hist([x1, x2], width=4)

# 1つめのデータのbinごとの個数を取得して2つめのhist()のbottomに設定
counts, _, _ = ax[1].hist(x1, width=4)
ax[1].hist(x2, bottom=counts, width=4)

# グラフタイトルの設定
ax[0].set_title('default')
ax[1].set_title('stack')

fig.tight_layout()

plt.show()

3つ以上の積み上げグラフ

データ数が3つ以上ある場合も同様の考え方で作成できます。

棒グラフ

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

# 目盛り(x方向)とランダム値(y方向)を生成
# あとの処理のためにデータをnumpy形式に変換しておく
x1 = np.array([i for i in range(20)])
y1 = np.array([np.random.randint(0, 100) for i in range(20)])

# 2つ目のデータ
y2 = np.array([np.random.randint(0, 100) for i in range(20)])  # 2つ目のデータ
y3 = np.array([np.random.randint(0, 100) for i in range(20)])  # 3つ目のデータ
y4 = np.array([np.random.randint(0, 100) for i in range(20)])  # 4つ目のデータ

fig, ax = plt.subplots(2, sharey=True)

# 横に並べて描画
# x座標は横に並べるために位置をシフト
ax[0].bar(x1 - 0.3, y1, width=0.2)
ax[0].bar(x1 - 0.1, y2, width=0.2)
ax[0].bar(x1 + 0.1, y3, width=0.2)
ax[0].bar(x1 + 0.3, y4, width=0.2)

# 2つ目以降のデータは前のデータの和をbottomに設定
ax[1].bar(x1, y1, width=0.4)
ax[1].bar(x1, y2, bottom=y1, width=0.4)
ax[1].bar(x1, y3, bottom=y1+y2, width=0.4)
ax[1].bar(x1, y4, bottom=y1+y2+y3, width=0.4)

# グラフタイトルの設定
ax[0].set_title('default')
ax[1].set_title('stack')

fig.tight_layout()
plt.show()

ヒストグラム

データが3つ以上ある場合も、stacked=Trueで対応可能です。

# ランダムな4つのデータ群を作成
x1 = [np.random.randint(0, 100) for i in range(200)]
x2 = [np.random.randint(0, 100) for i in range(200)]
x3 = [np.random.randint(0, 100) for i in range(200)]
x4 = [np.random.randint(0, 100) for i in range(200)]

fig, ax = plt.subplots(2, sharey=True)

# 4つのデータを並べたグラフを描画
ax[0].hist([x1, x2, x3, x4], width=2)

# 4つのデータをstack
ax[1].hist([x1, x2, x3, x4], width=2, stacked=True)

# タイトルの設定
ax[0].set_title('default')
ax[1].set_title('stack')

fig.tight_layout()

plt.show()

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です