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]),)
これは区切りが見にくいだけでなく、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. ]),)
最初のヒストグラムでは左から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()
と同じになります。特に日本では区間は○○以上○○未満という形で表すのが普通なので、Python のデフォルトのほうが自然に思えます。
seaborn では sns.histplot()
を使います。デフォルトでは次のようになります:
import seaborn as sns sns.histplot(x, bins=np.arange(11)/10)
オプションは plt.hist()
とだいたい同じですが、便利なオプションとして discrete=True
があります。これは整数値のヒストグラムを描く場合に便利です:
a = np.floor(10 * x) sns.histplot(a, discrete=True)
なお、さいころの目の分布のようなもともと離散分布のものは、棒グラフのように棒と棒の間隔をあけて描くのが一般的だろうと思います:
sns.histplot(a, discrete=True, shrink=0.8)
最後の2例を Matplotlib でするなら、それぞれ次のようになります:
plt.hist(a, bins=np.arange(min(a)-0.5, max(a)+1.5), edgecolor="black") plt.hist(a, bins=np.arange(min(a)-0.5, max(a)+1.5), edgecolor="black", rwidth=0.8)