matplotlib中的自定义直方图归一化

3
我正在尝试在matplotlib中制作归一化的直方图,但我希望它被归一化,使得总面积为1000。有没有办法做到这一点?
我知道要将其归一化为1,只需在plt.hist()的参数中包含density=True,stacked=True即可。同样的解决方案是这样做,并将每个柱子的高度乘以1000,如果这比更改直方图的归一化更容易实现。
非常感谢您的帮助!
3个回答

2
以下方法使用np.histogram计算每个直方图箱的计数。使用1000 / total_count / bin_width作为归一化因子,总面积将为1000。相反,要使所有条形图高度的总和为1000,则需要1000 / total_count的因子。 plt.bar用于显示最终结果。
示例代码使用density=True,计算相同的组合直方图,以与新直方图进行比较,其总和为1000。
import matplotlib.pyplot as plt
import numpy as np

data = [np.random.randn(100) * 5 + 10, np.random.randn(300) * 4 + 14, np.random.randn(100) * 3 + 17]
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 4))

ax1.hist(data, stacked=True, density=True)
ax1.set_title('Histogram with density=True')

xmin = min([min(d) for d in data])
xmax = max([max(d) for d in data])
bins = np.linspace(xmin, xmax, 11)
bin_width = bins[1] - bins[0]

counts = [np.histogram(d, bins=bins)[0] for d in data]
total_count = sum([sum(c) for c in counts])
# factor = 1000 / total_count # to sum to 1000
factor = 1000 / total_count / bin_width # for an area of 1000
thousands = [c * factor for c in counts]

bottom = 0
for t in thousands:
    ax2.bar(bins[:-1], t, bottom=bottom, width=bin_width, align='edge')
    bottom += t
ax2.set_title('Histogram with total area of 1000')

plt.show()

stacked histogram summing to 1000


0

一个简单的方法是设置第二个y轴,其刻度标签为原始值乘以1000,然后隐藏原始轴的刻度:

import matplotlib.pyplot as plt
import numpy as np

data = [np.random.randn(5000)]
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

#hist returns a tuple that contains a list of y values at its 0 index:
y,_,_ = ax1.hist(data, density=True, bins=10, edgecolor = 'black')

#find max y value of histogram and multiply by 1000:
max_y = np.round(y.max(),1)*1000

#set up the second y-axis ticks as increments of max_y:
ax2.set_ylim(0,max_y)
ax2.set_yticks(np.linspace(0, max_y, 9))

#hide original y-axis ticks:
ax1.axes.yaxis.set_ticks([])
plt.show()

enter image description here


0
另一种做事的方式是使用权重。 plt.hist()函数有一个可选的关键字参数weights,如果你使用一个与数据形状相同的数组,并将每个条目设置为1000(类似于weights= 1000 * np.ones(data.size)),那么你实际上是将每一列乘以1000。
很抱歉没有提供代码示例,我没有时间,也没有足够的声望来留下评论 :-(

1
你的回答可以通过提供更多支持性的信息来改进。请编辑以添加进一步的细节,比如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到更多关于如何撰写好回答的信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接