27

这是此答案的后续问题。我正在尝试绘制标准化直方图,但不是将 1 作为 y 轴上的最大值,而是得到不同的数字。

对于数组 k=(1,4,3,1)

 import numpy as np

 def plotGraph():
   
    import matplotlib.pyplot as plt
    
    k=(1,4,3,1)

    plt.hist(k, normed=1)

    from numpy import *
    plt.xticks( arange(10) ) # 10 ticks on x axis

    plt.show()  
    
plotGraph()

我得到这个直方图,看起来不像规范。

在此处输入图像描述

对于不同的数组 k=(3,3,3,3)

 import numpy as np

 def plotGraph():
   
    import matplotlib.pyplot as plt
    
    k=(3,3,3,3)

    plt.hist(k, normed=1)

    from numpy import *
    plt.xticks( arange(10) ) # 10 ticks on x axis

    plt.show()  
    
plotGraph()

我得到这个直方图,最大 y 值为 10。

在此处输入图像描述

对于不同的 k,即使 normed=1 或 normed=True,我也会得到不同的 y 最大值。

为什么标准化(如果有效)会根据数据发生变化,如何使 y 的最大值等于 1?

更新:

我正在尝试通过在 matplotlib 中绘制条形高度总和为 1 的直方图来实现Carsten König的答案,并得到非常奇怪的结果:

import numpy as np

def plotGraph():

    import matplotlib.pyplot as plt

    k=(1,4,3,1)

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

    from numpy import *
    plt.xticks( arange(10) ) # 10 ticks on x axis

    plt.show()  

plotGraph()

结果:

在此处输入图像描述

我究竟做错了什么?

4

5 回答 5

32

绘制归一化直方图时,曲线下的面积总和应为 1,而不是高度。

In [44]:

import matplotlib.pyplot as plt
k=(3,3,3,3)
x, bins, p=plt.hist(k, density=True)  # used to be normed=True in older versions
from numpy import *
plt.xticks( arange(10) ) # 10 ticks on x axis
plt.show()  
In [45]:

print bins
[ 2.5  2.6  2.7  2.8  2.9  3.   3.1  3.2  3.3  3.4  3.5]

在此示例中,bin 宽度为 0.1,曲线下方的面积总和为 1 (0.1*10)。

x存储每个箱的高度。p存储每个单独的 bin 对象(实际上,它们是patches. 所以我们只是总结x并修改每个 bin 对象的高度。

要使高度之和为 1,请在之前添加以下内容plt.show()

for item in p:
    item.set_height(item.get_height()/sum(x))

在此处输入图像描述

于 2014-03-07T04:34:19.850 回答
13

您可以使用此处列出的解决方案:

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)
于 2017-05-05T04:41:14.113 回答
5

一种方法是自己获取概率,然后绘制plt.bar

In [91]: from collections import Counter
    ...: c=Counter(k)
    ...: print c
Counter({1: 2, 3: 1, 4: 1})

In [92]: plt.bar(c.keys(), c.values())
    ...: plt.show()

结果: 在此处输入图像描述

于 2014-03-07T04:46:38.357 回答
4

定义规范直方图,使得每列的宽度和高度的乘积之和等于总数。这就是为什么你没有让你的最大值等于一。

但是,如果您仍然想强制它为 1,您可以通过以下方式使用 numpy 和 matplotlib.pyplot.bar

sample = np.random.normal(0,10,100)
#generate bins boundaries and heights
bin_height,bin_boundary = np.histogram(sample,bins=10)
#define width of each column
width = bin_boundary[1]-bin_boundary[0]
#standardize each column by dividing with the maximum height
bin_height = bin_height/float(max(bin_height))
#plot
plt.bar(bin_boundary[:-1],bin_height,width = width)
plt.show()
于 2017-01-18T18:24:35.270 回答
0

我发现它很容易使用 plotly express。这是我的示例代码:

import plotly.express as px
k= [1,4,3,1]
px.histogram(k,nbins=10,range_x=[0,10],histnorm='probability')

在此处输入图像描述

这以您想要的方式给出了归一化直方图。如果您想使用百分比而不是概率,您只需将最后一行代码更改为

px.histogram(k,nbins=10,range_x=[0,10],histnorm='percent')

如果您不想手动设置 range_x 和 nbins 以确保直方图的区域始终为 1,则可以使用以下代码:

x_min=int(min(k))-1
x_max=int(max(k))+1
x_bins = x_max-x_min
px.histogram(k,nbins=x_bins,range_x=[x_min,x_max],histnorm='probability')

在此处输入图像描述

于 2022-02-04T01:53:58.123 回答