pythonでヒストグラムを正規化する

pythonヒストグラムを正規化(面積を1.0にする)する方法です

サンプルコード

import numpy as np
import matlplotlib.plt as plt


data=[1,2,2,3,3,3,4,4,4,4]

# 正規化されたヒストグラムを計算する
hist, edges = np.histogram(data, density=True)
w = edges[1] - edges[0]
hist = hist * w

# グラフにプロット
plt.bar(edges[:-1], hist, w)

# 正規化されていることを確認
print( sum(hist) )

注意点

normed=True は使わない

オプション normed は挙動が紛らわしいという欠点があったため廃止となりました.

ネット上には normed=True を使う例が散見されますが,それは過去の話です.無視しましょう.

density=True では正規化されない

ネット上には normed の変わりに density を使えという記載もありますが,これも間違いです.

np.histgram() や plt.hist() で density=True を指定してもヒストグラムは正規化されません*1

たとえば以下のコードを実行しても sum(hist) は1.0 にはなりません

data=[1,2,2,3,3,3,4,4,4,4]
hist, edges = np.histogram(data, density=True)
print( sum(hist) )
# 結果は3.3が表示される.つまりhistは 正規化されてない

sum(hist)が1.0になるようにするには

# ヒストグラムを計算,正規化する
hist, edges = np.histogram(data, density=True)
w = edges[1] - edges[0]
hist = hist * w

print( sum(hist) )

と言った感じのコードが必要になります

*1:厳密には,たまたま w=1 となるようなデータの場合は density=True を指定するだけで正規化されます