2
4

More than 1 year has passed since last update.

【matplotlib】ヒストグラムを密度ではなく確率で規格化する方法

Posted at

概要

matplotlibでヒストグラムを作っていると、縦軸を密度ではなく確率で規格化したい場合があると思う。この記事では、縦軸を確率にしたヒストグラムの作り方について紹介する。
まず、例として、以下の図のような場合がある。横軸に特に意味がない量が割り当てれている場合や、各ビンに入る確率を知りたい場合などに右図のように縦軸に確率が使われる。
image.png

実装コード

Google Colabで作成した本記事のコードは、こちらにあります。

各種インポート

各種インポート
import numpy as np
import matplotlib.pyplot as plt

実行時の各種バージョン

Name Version
numpy 1.21.6
matplotlib 3.2.2

使用データ

まずは、縦軸カウント数の本記事で使用する0~1の一様乱数のデータをヒストグラムに表示する。

縦軸カウント数
np.random.seed(2022)
data = np.random.rand(1000)
bins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist(data, bins)
ax.set_xlabel('data')
ax.set_ylabel('counts')
plt.show()

出力結果
image.png

縦軸密度

縦軸を密度にしてヒストグラムに表示する。density=Trueは、ヒストグラムの面積が1になるように計算される。

縦軸密度
np.random.seed(2022)
data = np.random.rand(1000)
bins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist(data, bins, density=True)
ax.set_xlabel('data')
ax.set_ylabel('density')
plt.show()

出力結果
image.png

縦軸確率

各ビンに入る確率を知りたい場合がある。そこで、縦軸を確率にしてヒストグラムに表示する。

目標とする図
image.png

方法1

weightsで重みを指定して確率のヒストグラムを表示する方法である。
このweightsは各配列の要素の重みをどうするかの引数で、例えばweights=np.ones(len(data)) / 1とすると、各配列の要素の値を1として重みをつける。すなわち、縦軸カウント数と全く同じヒストグラムができる。
では、weights=np.ones(len(data)) / len(data)とするとどうなるでしょうか。各配列の要素数をdata数が1000個の場合、重みが1/1000として扱われる。つまり、各配列の要素の重みの合計が1となり縦軸確率のヒストグラムができる。

np.random.seed(2022)
data = np.random.rand(1000)
bins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist(data, bins, weights=np.ones(len(data)) / len(data))
ax.set_xlabel('data')
ax.set_ylabel('probability')
plt.show()

方法2

np.histogramcountsbinを一旦渡して、weightsで重みを指定して確率のヒストグラムを表示する方法である。方法を順を追って説明する。

  1. countsbinsに各ビンと各ビンに入るカウント数を渡す。
  2. ax.hist(bins[:-1], bins)を表示すると良く理解できるが、このax.hist(bins[:-1], bins)は各ビンに1つのみ必ず入るので、全てが1のヒストグラムができる。
  3. 全てが1のヒストグラムをweightsで重みをつける。weights=countsとすると、各ビンが1なので1 * countsの、すなわち縦軸がカウント数のヒストグラムができる。
  4. 確率のヒストグラムを作りたいので、各ビンを全体のdata数で割ってあげて重みをつける。つまり、weights=counts / len(data)とすると縦軸確率のヒストグラムができる。
np.random.seed(2022)
data = np.random.rand(1000)
counts, bins = np.histogram(data, np.linspace(0, 1, 10))

fig, ax = plt.subplots()
ax.hist(bins[:-1], bins, weights=counts / len(data))
ax.set_xlabel('data')
ax.set_ylabel('probability')
plt.show()

まとめ

ヒストグラムの縦軸を確率で表示する方法を紹介しました。誰かのお役に立てれば幸いです。

参考資料

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4