ヒストグラム

Matplotlibのヒストグラム

Python の Matplotlib のデフォルトのヒストグラムです:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(12345)
x = rng.random(1000)
plt.hist(x)
(array([ 94., 102., 109., 109., 112.,  94.,  97.,  99.,  85.,  99.]),
 array([4.37086824e-04, 1.00314361e-01, 2.00191635e-01, 3.00068909e-01,
        3.99946182e-01, 4.99823456e-01, 5.99700730e-01, 6.99578004e-01,
        7.99455278e-01, 8.99332552e-01, 9.99209826e-01]),
 )
ヒストグラム1

これは区切りが見にくいだけでなく、0.0 から 1.0 までが10等分されたように見えて、実は最小値 4.37086824e-04 から最大値 9.99209826e-01 までの区間が10等分されたもので、区切り位置は [0, 0.1, 0.2, …, 1] になっていません。

正しく描くには、次のようにビン(階級)の指定を明確にする必要があります:

plt.hist(x, color="lightgray", edgecolor="black", bins=np.arange(11)/10)
(array([ 94., 102., 109., 110., 111.,  94.,  97.,  99.,  85.,  99.]),
 array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]),
 )
ヒストグラム2

最初のヒストグラムでは左から3番目と4番目が同じ高さでしたが、正しく描いたヒストグラムでは3番目より4番目が高くなっています。

ここで np.arange(11) は 0 から 10 まで11個の整数の配列を意味します。これを10で割って、0 から 1 まで 0.1 刻みの配列にしています。このように与えると、10個の左閉区間 [0, 0.1)、[0.1, 0.2)、…、[0.9, 1.0] がビンになります。最後のビンだけ両側閉区間となることにご注意ください。

オプション density=True で縦軸が個数でなく密度になります。orientation="horizontal" で横向きになります。

左が閉じた区間になるのは、R のデフォルトとは逆で、R ではオプション right=FALSE を付けると plt.hist() と同じになります。ちなみに Excel の「グラフ」メニューに加わった「ヒストグラム」も左開区間にしかできないようです。

seabornのヒストグラム

seaborn では sns.histplot() を使います。デフォルトでは次のようになります:

import seaborn as sns

sns.histplot(x, bins=np.arange(11)/10)
ヒストグラム4

オプションは plt.hist() とだいたい同じですが、便利なオプションとして discrete=True があります。これは整数値のヒストグラムを描く場合に便利です:

sns.histplot(np.floor(10 * x), discrete=True)
ヒストグラム5

同様のことを Matplotlib でするなら、次のようになります:

a = np.floor(10 * x)
plt.hist(a, bins=np.arange(min(a)-0.5, max(a)+1.5), edgecolor="black")