matplotlib/pandas 中是不是有参数将直方图的 Y 轴作为百分比?
Posted
技术标签:
【中文标题】matplotlib/pandas 中是不是有参数将直方图的 Y 轴作为百分比?【英文标题】:Is there a parameter in matplotlib/pandas to have the Y axis of a histogram as percentage?matplotlib/pandas 中是否有参数将直方图的 Y 轴作为百分比? 【发布时间】:2013-07-26 07:02:09 【问题描述】:我想比较两个直方图,让 Y 轴显示每列占整个数据集大小的百分比,而不是绝对值。那可能吗?我正在使用熊猫和 matplotlib。 谢谢
【问题讨论】:
将normed=True
添加到您的plt.hist()
。
谢谢!由于某种原因,该选项未记录在 pandas.pydata.org/pandas-docs/dev/generated/… 中。但是,我在 Y 轴上得到的值等于且大于 1(例如 1.4)。知道这怎么可能吗?我的直觉是,一旦标准化,值应该在 0-1 之间。
第二个问题!
不推荐使用“规范”kwarg,并已被“密度”取代
【参考方案1】:
density=True
(normed=True
for matplotlib < 2.2.0
)返回一个直方图,其中np.sum(pdf * np.diff(bins))
等于 1。如果您希望直方图的总和为 1,您可以使用 Numpy 的 histogram() 并自己标准化结果.
x = np.random.randn(30)
fig, ax = plt.subplots(1,2, figsize=(10,4))
ax[0].hist(x, density=True, color='grey')
hist, bins = np.histogram(x)
ax[1].bar(bins[:-1], hist.astype(np.float32) / hist.sum(), width=(bins[1]-bins[0]), color='grey')
ax[0].set_title('normed=True')
ax[1].set_title('hist = hist / hist.sum()')
顺便说一句:左侧绘图的第一个 bin 出现奇怪的绘图故障。
【讨论】:
太棒了(也是如何使用子图的一个很好的例子) 你能解释一下为什么熊猫会这样吗?我有点困惑。我想大多数人会选择 sum =1 的方式。 normed 在 matplotlib 2.2.0 版中已弃用;请改用 density 关键字参数。 matplotlib.org/api/_as_gen/matplotlib.pyplot.hist.html 参数density=True
不会按总计数对直方图进行归一化。也就是说,条形的高度之和不会为 1(而是当density=True
时,高度*宽度之和为 1,这不是人们说规范化直方图时的想法)。要标准化直方图,请参阅此github.com/matplotlib/matplotlib/issues/10398/… 或此***.com/a/16399202
有趣的是normed=True
已被弃用。这是一个直观且有用的参数;我以前经常使用它。【参考方案2】:
Pandas 绘图可以接受来自相应 matplotlib 函数的任何额外关键字参数。因此,为了从这里其他人的 cmets 中获得完整性,这就是人们将如何做到的:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(100,2), columns=list('AB'))
df.hist(density=1)
另外,为了直接比较,这也可能是一个好方法:
df.plot(kind='hist', density=1, bins=20, stacked=False, alpha=.5)
【讨论】:
【参考方案3】:看起来像@CarstenKönig found the right way:
df.hist(bins=20, weights=np.ones_like(df[df.columns[0]]) * 100. / len(df))
【讨论】:
我认为100
放错了位置。正确的版本是df.hist(bins=20, weights=np.ones_like(df[df.columns[0]]) * 100. / len(df))
,以防你想到的是从 0 到 100 的数字。
确实如此。接得好!已更正。【参考方案4】:
我知道这个答案是 6 年后的事,但对于任何使用密度 = True(normed = True 的替代品)的人来说,这并不是你想做的。它将对整个分布进行归一化,使箱的面积为 1。因此,如果您有更多宽度 1(y 轴)。如果您想将直方图绑定到 [0;1],则必须自己计算。
【讨论】:
这也是我发现的 或者可能是df["col"].plot.hist(ax=ax, cumulative=true, weights=list(100*numpy.ones_like(df.index)/len(df.index)))
和ax.yaxis.set_major_formatter(plt.FuncFormatter(':.0f%'.format))
之类的东西。不是在公园里散步,但可以工作。【参考方案5】:
您可以使用 np.ones_like() 来简化权重:
df["ColumnName"].plot.hist(weights = np.ones_like(df.index) / len(df.index))
np.ones_like() 可以使用 df.index 结构
len(df.index) 对于大型 DataFrame 更快
【讨论】:
由于某种原因,该命令给了我错误ValueError: weights should have the same shape as x
(matplotlib 3.0.3)。对我有用的命令是df["ColumnName"].plot.hist(weights = list(np.ones_like(df.index) / len(df.index)))
【参考方案6】:
我知道这是一个老问题,但它在某些搜索中显示在顶部,所以我认为从 2021 年开始,seaborn 将是一个简单的方法。
你可以这样做:
import seaborn as sns
sns.histplot(df,stat="probability")
【讨论】:
以上是关于matplotlib/pandas 中是不是有参数将直方图的 Y 轴作为百分比?的主要内容,如果未能解决你的问题,请参考以下文章
数据可视化实例: 带线性回归最佳拟合线的散点图(matplotlib,pandas)
绘制/计算指数曲线的问题(python、matplotlib、pandas)
如何使用 Matplotlib、pandas 和 sklearn 创建线性回归图?