在 matplotlib 直方图中设置相对频率
Posted
技术标签:
【中文标题】在 matplotlib 直方图中设置相对频率【英文标题】:Setting a relative frequency in a matplotlib histogram 【发布时间】:2012-04-03 18:22:17 【问题描述】:我将数据作为浮点数列表,我想将其绘制为直方图。 Hist() 函数可以完美地绘制绝对直方图。但是,我不知道如何以相对频率格式来表示它——我想将它作为一个分数,或者理想情况下作为 y 轴上的一个百分比。
代码如下:
fig = plt.figure()
ax = fig.add_subplot(111)
n, bins, patches = ax.hist(mydata, bins=100, normed=1, cumulative=0)
ax.set_xlabel('Bins', size=20)
ax.set_ylabel('Frequency', size=20)
ax.legend
plt.show()
我认为 normed=1 参数会做到这一点,但它给出的分数太高,有时大于 1。它们似乎也取决于 bin 大小,好像它们没有被 bin 大小或其他东西标准化.然而,当我设置累积 = 1 时,它很好地总结为 1。那么,问题在哪里?顺便说一句,当我将相同的数据输入 Origin 并绘制它时,它给了我完全正确的分数。谢谢!
【问题讨论】:
你为什么用引号说 "list",你的数据有什么特别之处吗?你是如何存储它的?您还将数据称为Data
,这很奇怪,因为 Python 命名约定规定 CamelCase
保留用于类名 - 请参阅 PEP 8 python.org/dev/peps/pep-0008。
抱歉误导。我只是不确定说明数据类型和参数等的约定。因此,我编辑了原始帖子以删除所有引号。这只是整个代码的和平,为了简化,我重命名了变量只是为了在这里发布它。在原始代码中,它们的名称对我有意义,但与问题无关,因为其余代码工作得很好。我现在将它的数据重命名为 mydata。
不用担心,只是让您知道。为改进问题喝彩,让每个人都做得更好。
normed
已弃用。您可以改用density
。它使积分(不是总和)等于 1。
【参考方案1】:
因为 hist 的 normed 选项返回点的密度,例如 dN/dx
你需要的是这样的:
# assuming that mydata is an numpy array
ax.hist(mydata, weights=np.zeros_like(mydata) + 1. / mydata.size)
# this will give you fractions
【讨论】:
这已经解决了问题。确实非常迅速的帮助。仍然存在一个问题,我如何将其表示为百分比而不是分数,即如果没有默认参数,我如何修改 y 轴值。再次感谢! 如果你想要百分比,只需使用 ax.hist(mydata, weights=np.zeros_like(data) + 100./data.size) 好的,现在我知道了权重的实际用途。再次感谢! 我认为是一样的:np.ones_like(data) / data.size 我很感激,虽然我不得不使用 len(data)【参考方案2】:也可以使用set_major_formatter
调整y轴的刻度,如下:
from matplotlib import ticker as tick
def adjust_y_axis(x, pos):
return x / (len(mydata) * 1.0)
ax.yaxis.set_major_formatter(tick.FuncFormatter(adjust_y_axis))
只需在plt.show()
之前调用adjust_y_axis
即可。
【讨论】:
为什么要乘以1.0
?【参考方案3】:
对于相对频率格式,设置选项density=True
。下图显示了 1000 个样本的直方图,取自均值为 5,标准差为 2.0 的正态分布。
代码是
import numpy as np
import matplotlib.pyplot as plt
# Generate data from normal distibution
mu, sigma = 5, 2.0 # mean and standard deviation
mydata = np.random.normal(mu, sigma, 1000)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.hist(mydata,bins=100,density=True);
plt.show()
如果您想在 y 轴上显示 %,您可以使用 PercentFormatter
,如下所示
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
# Generate data from normal distibution
mu, sigma = 5, 2.0 # mean and standard deviation
mydata = np.random.normal(mu, sigma, 1000)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.hist(mydata,bins=100,density=False);
ax.yaxis.set_major_formatter(PercentFormatter(xmax=100))
plt.show()
【讨论】:
答案不对。将density
设置为 true 意味着直方图上的积分是 1,但并不是所有的 bin 加起来都是 100%。以上是关于在 matplotlib 直方图中设置相对频率的主要内容,如果未能解决你的问题,请参考以下文章
Matplotlib(3直方图) - plt.hist()参数解释&应用实例
python使用matplotlib可视化归一化的直方图(histogram)Y轴坐标为比例而非频率自定义直方图箱图不填充(normalizing a histogram)