HOWTO · Matplotlib

Matplotlib でビンのサイズを手動で設定する方法

Matplotlib の1次元ヒストグラムでビン幅を調整するには、`plt.hist()` の `bins` 引数に境界値の列を渡します。

このページの内容

1次元の Matplotlib ヒストグラムでビン幅を調整するには、データと境界値の列を plt.hist(..., bins=...) に渡します。隣り合う境界値が1つの区間を定義するため、列を指定すれば幅が同じビンも異なるビンも作成できます。hist2d() は2次元ヒストグラム用です。ここでは plt.hist() を使います。

hist() 関数の引数としてビン境界を指定する

区間の開始位置と終了位置を自分で決めたい場合は、境界値の列を使います。たとえば [0, 10, 20, 30, 40, 50, 60, 80, 100] を指定すると、8つのビンができます。最初の6つの幅は10、最後の2つの幅は20です。ビンの数は境界値の数より1つ少なくなります。最初または最後の境界の外にある値はヒストグラムに含まれないため、対象のデータをすべて含む範囲を選んでください。

すべてのビンを同じ幅にするには、np.arange で等間隔の境界値を生成します。次の例では、同じ値に対して、指定した境界値と等幅の境界値を比較します。np.arange(start, stop, step) は start を含み、stop を含みません。最大値を含めるには、stop をその値より大きくしてください。

import matplotlib.pyplot as plt
import numpy as np

values = np.array([3, 8, 12, 18, 24, 31, 37, 43, 52, 61, 74, 88, 96])
width = 10
explicit_edges = [0, 10, 20, 30, 40, 50, 60, 80, 100]
equal_edges = np.arange(0, 101, width)

fig, axes = plt.subplots(1, 2, figsize=(10, 4))
axes[0].hist(values, bins=explicit_edges)
axes[0].set_title("Chosen boundaries")
axes[1].hist(values, bins=equal_edges)
axes[1].set_title("Equal-width bins")
for axis in axes:
    axis.set_xlabel("Value")
    axis.set_ylabel("Count")
fig.tight_layout()
plt.show()

境界値のリストを指定した Matplotlib ヒストグラム

データから等幅のビンを作る場合は、max(values) + width を stop にすると便利です。np.arange は stop を含まないため、その値自体は境界になりません。この例では stop は106で、最後に生成される境界値は100です。最大の観測値96も範囲に含まれます。データの範囲や幅が変わる場合は、固定のリストを使わず、現在のデータから境界値を計算してください。

等間隔のビン境界を使った Matplotlib ヒストグラム

希望する幅からビン数を計算する

データの範囲がプログラムの実行時に初めてわかる場合は、観測値から最初と最後の境界値を求めます。この例では、最初の境界値を指定幅の倍数まで切り下げ、最後の境界値を最大値以上となる倍数まで広げます。空でない数値データと正の幅を前提としています。両端のビンはデータの範囲を超えることがありますが、隣り合う境界値の間隔はどこも指定した幅になります。

import matplotlib.pyplot as plt
import numpy as np

values = np.array([3, 8, 12, 18, 24, 31, 37, 43, 52, 61, 74, 88, 96])
width = 10.0
first_edge = np.floor(values.min() / width) * width
last_edge = np.ceil(values.max() / width) * width
edges = np.arange(first_edge, last_edge + width, width)

plt.hist(values, bins=edges)
plt.xlabel("Value")
plt.ylabel("Count")
plt.title(f"Histogram with bin width {width:g}")
plt.show()

指定幅から算出したビン境界

この例では最小値が3、最大値が96なので、境界値は0から100まで10刻みで生成されます。観測値は各区間に集計され、プロットされるヒストグラムのビン幅は指定した幅になります。別の幅を使う場合は width を更新してください。同じ計算で対応する境界値の列が生成されます。データが空の場合や幅が正でない場合は、境界値を計算する前にその入力を処理してください。