LoginSignup
33
27

More than 5 years have passed since last update.

matplotlib:histgram normedの挙動

Last updated at Posted at 2017-02-28

matplotlibでhistgram

matplotlibでヒストグラムを作る際にハマったことのメモ

normedの落とし穴

matplotlibでヒストグラムをつくるときに使う matplotlib.axes.Axes.hist() もしくは matplotlib.pyplot.hist() には恐ろしい落とし穴が存在するのでメモしておく。ヒストグラムを作るときに頻度を正規化するためにnormed=1というオプションをつけることが多々ある。しかし、このoptionをつけたのにも関わらず、以下のようなヒストグラムになることがある。

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
nor = np.random.normal(0,0.5,1000)
plt.hist(nor,normed=1,range=(-3,3),bins=300)
plt.savefig("test.pdf")

c0e82554-a3d9-11f4-b7c0-58dd5fe0b006.png

え、y軸の目盛りの値が1より大きい。。

当初、これをバグだと思っていた筆者は無理やりbarplotを用いてヒストグラムを書こうとした。しかし、面倒過ぎる。seabornのdistplotならと思ってみたが、同じ問題を抱えていてダメ。謎だなぁと思っていたら、あることに気づいた。

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
nor = np.random.normal(0,0.5,1000)
plt.hist(nor,normed=1,range=(-3,3),bins=6)
plt.savefig("test.pdf")

5170b571-cc4a-88b6-b414-dec61b28d729.png

binの幅が1なら正常に動くじゃん。 まさか、、
なんと、binの面積の合計が1になるように正規化されている。 実際に、numpyのhistogram関数(matplotlibのhistと挙動は一緒)をつかってデータの詳細をみてみると

import numpy as np
np.random.seed(0)
nor = np.random.normal(0,0.5,1000)
hist,pos = np.histogram(nor,normed=1,range=(-3,3),bins=300)
print(np.sum(hist))
#50.0
print(np.sum(hist)*6.0/300)
#1.0

となる。よって、以下のようにコードを書きかえて上げればいい。

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
nor = np.random.normal(0,0.5,1000)
binnum = 300
fig = plt.figure()
ax = plt.subplot(111)
ax.hist(nor,normed=1,range=(-3,3),bins=binnum)
ax_yticklocs = ax.yaxis.get_ticklocs()#目盛りの情報を取得
ax_yticklocs = list(map(lambda x: x * len(range(-3,3))*1.0/binnum, ax_yticklocs))#元の目盛りの値にbinの幅を掛ける
ax.yaxis.set_ticklabels(list(map(lambda x: "%0.2f" % x, ax_yticklocs)))直した目盛りを表示
plt.savefig("test.pdf")

iTerm2.xULA2R.test copy.png

これで、多分望みどおりの目盛りができてるはず。しかし、この実装はわかりにくい、、、。

33
27
2

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
33
27