web-dev-qa-db-ja.com

matplotlibでバーの高さが合計1になるヒストグラムをプロットする

Matplotlibを使用して、ベクトルから正規化されたヒストグラムをプロットしたいと思います。私は次を試しました:

plt.hist(myarray, normed=True)

と同様:

plt.hist(myarray, normed=1)

しかし、どちらのオプションも[0、1]からy軸を生成しないため、ヒストグラムのバーの高さは1になります。このようなヒストグラムを作成したいのですが、どうすればよいですか

ありがとう!

73
user248237

より完全な(またはこの場合は動作しない)例を提供する方が便利です。

私は次を試しました:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.randn(1000)

fig = plt.figure()
ax = fig.add_subplot(111)
n, bins, rectangles = ax.hist(x, 50, density=True)
fig.canvas.draw()
plt.show()

これにより、[0,1]からのy軸を持つ棒グラフヒストグラムが実際に生成されます。

さらに、histドキュメント(つまり、ipythonからのax.hist?)に従って、合計も問題ないと思います。

*normed*:
If *True*, the first element of the return Tuple will
be the counts normalized to form a probability density, i.e.,
``n/(len(x)*dbin)``.  In a probability density, the integral of
the histogram should be 1; you can verify that with a
trapezoidal integration of the probability density function::

    pdf, bins, patches = ax.hist(...)
    print np.sum(pdf * np.diff(bins))

上記のコマンドの後にこれを試してください:

np.sum(n * np.diff(bins))

期待どおり1.0の戻り値を取得します。 normed=Trueは、各バーの値の合計が単一であることを意味するのではなく、バー全体の積分ではなく単一であることを忘れないでください。私の場合、np.sum(n)はおよそ7.2767を返しました。

42
dtlussier

すべてのバーの合計を1に等しくする場合は、値の総数で各ビンに重みを付けます。

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)

スレッドはかなり古いですが、それが役立つことを願っています...

182
Carsten König

質問の日付が2010年であることを考えると、この回答は遅すぎることはわかっていますが、私自身も同様の問題に直面していたため、この質問に出くわしました。回答ですでに述べたように、normed = Trueは、ヒストグラムの下の合計面積が1に等しいが、高さの合計が1に等しくないことを意味します。しかし、ヒストグラムの物理的な解釈の便宜上、高さの合計が1に等しい.

次の質問にヒントを見つけました- Python:エリアが1以外に正規化されたヒストグラム

しかし、バーをhistt​​ype = "step"機能hist()に似せる方法を見つけることができませんでした。これは私を迂回させました: Matplotlib-既にビニングされたデータを持つステップヒストグラム

コミュニティがそれを受け入れられると判断した場合、上記の両方の投稿からアイデアを統合するソリューションを提案したいと思います。

import matplotlib.pyplot as plt

# Let X be the array whose histogram needs to be plotted.
nx, xbins, ptchs = plt.hist(X, bins=20)
plt.clf() # Get rid of this histogram since not the one we want.

nx_frac = nx/float(len(nx)) # Each bin divided by total number of objects.
width = xbins[1] - xbins[0] # Width of each bin.
x = np.ravel(Zip(xbins[:-1], xbins[:-1]+width))
y = np.ravel(Zip(nx_frac,nx_frac))

plt.plot(x,y,linestyle="dashed",label="MyLabel")
#... Further formatting.

場合によっては、ヒストグラムの左端の「バー」または右端の「バー」がY軸の最下点に触れても閉じないことに気付きました。そのような場合、要求0またはyの最後に要素0を追加すると、必要な結果が得られました。

私は自分の経験を共有すると思った。ありがとうございました。

18
Killer

np.histogram()メソッドを使用した別の簡単なソリューションを次に示します。

myarray = np.random.random(100)
results, edges = np.histogram(myarray, normed=True)
binWidth = edges[1] - edges[0]
plt.bar(edges[:-1], results*binWidth, binWidth)

実際に、合計が最大1になることを次のコマンドで確認できます。

> print sum(results*binWidth)
1.0
10
Yuri Brovman