Matplotlib直方图概率密度绘制异常:如何获取正确概率值?
解决Matplotlib概率密度直方图与预期频率不符的问题
问题原因
你混淆了概率密度和**相对频率(概率)**的概念:
density=True会让直方图的总面积为1,每个条形的高度是「频率 / 对应bin的宽度」。你设置了bins=100,每个bin的宽度是(3-1)/100=0.02,所以数字1的密度计算为0.5 / 0.02 = 2.5,这就是你看到的结果。- 你预期的是相对频率(即每个数值出现的占比),这和概率密度不是同一个概念。
解决方案
方法1:调整bins适配离散数据,用density=True
针对离散数值,设置bins让每个数值单独占一个bin,此时bin宽度为1,概率密度就等于相对频率:
import matplotlib.pyplot as plt test = [1,2,3,1,1,3,2,1] # 设置bins,让每个数字落在独立区间内 bins = [0.5, 1.5, 2.5, 3.5] plt.hist(test, bins=bins, density=True) plt.xticks([1,2,3]) plt.show()
方法2:用weights参数直接绘制相对频率
给每个样本设置权重为1/总样本数,不需要density=True,条形高度直接是相对频率:
import matplotlib.pyplot as plt test = [1,2,3,1,1,3,2,1] n = len(test) # 每个样本的权重为1/n,总和为1 plt.hist(test, bins=100, weights=[1/n]*n) plt.xticks([1,2,3]) plt.show()
方法3:用Seaborn绘制更直观的离散频率图
对于离散数据,用countplot或barplot展示频率更清晰:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd test = [1,2,3,1,1,3,2,1] df = pd.DataFrame({'value': test}) # 先计算频率 freq_df = df['value'].value_counts(normalize=True).reset_index() freq_df.columns = ['value', 'frequency'] sns.barplot(data=freq_df, x='value', y='frequency') plt.ylim(0, 1) plt.show()
内容的提问来源于stack exchange,提问作者q2w3e4
相关产品推荐
相关产品推荐

