matplotlib直方图设置Density参数后概率密度求和不为1的调整咨询
原因说明
density=True的作用是将直方图的概率密度标准化,满足「所有区间的(密度值 × 区间宽度)之和为1」,而非密度值本身之和为1。你当前设置了bins=10、range=(0,100),每个区间宽度为10,因此密度值的总和约为0.1,属于正常现象。
调整方法
根据你的需求可以选择以下两种方案:
方案1:y轴显示区间占比(所有区间占比相加总和为1,最常用)
不需要使用density参数,改为给每个样本分配权重即可,修改对应代码如下:
import pandas as pd import matplotlib.pyplot as plt from matplotlib.ticker import PercentFormatter plt.style.use('seaborn-deep') input_file = r'\\CP\file.xls' df = pd.read_excel(input_file,header=6) df_Fund=df[(df['Port. Weight']>0)] df_Bench=df[(df['Bench. Weight']>0)] x = df_Fund['Delta'] y = df_Bench['Delta'] # 新增:计算每个样本的权重,确保所有区间占比和为1 weights_x = [1 / len(x)] * len(x) weights_y = [1 / len(y)] * len(y) # 替换density参数为weights plt.hist([x,y], bins=10, range=(0,100), weights=[weights_x, weights_y], label=['Fund','Bench']) plt.legend(loc='upper right') plt.gca().yaxis.set_major_formatter(PercentFormatter(1)) plt.title('Delta Breakdown') # 修正:原赋值写法不会实际设置图表标题 plt.show()
修改后每个区间的y值就是该区间样本占对应序列总样本的比例,所有区间比例相加等于1。
方案2:保留概率密度定义,仅调整显示逻辑
如果你确实需要使用概率密度数值,只需要修改百分比格式化的参数,将xmax设置为区间宽度(即10)即可,格式化后会自动转换为对应占比:
plt.gca().yaxis.set_major_formatter(PercentFormatter(xmax=10))
内容的提问来源于stack exchange,提问作者Ben Brando
相关产品推荐
相关产品推荐

