You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为对数分箱的Mass直方图添加趋势曲线?

给对数分箱直方图添加趋势曲线

嘿,我来帮你搞定这个对数分箱直方图的趋势曲线问题!你的现有代码已经搭好了对数分箱的直方图框架,现在只需要添加趋势曲线的计算和绘制逻辑就行。因为是对数坐标轴,直接在原始空间拟合容易出数值问题,所以我们可以在对数空间处理后再转换回来,或者用核密度估计(KDE)生成平滑趋势线。

下面是修改后的完整代码,我会逐部分解释:

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde  # 用于生成平滑的核密度估计曲线

# 假设Mass是你的预定义变量,这里先模拟一组符合范围的测试数据
np.random.seed(42)
Mass = np.logspace(43, 45, 1000) * np.random.lognormal(0, 0.3, 1000)

# 生成对数分箱:直接用Mass的最小/最大值生成,比基于线性分箱转换更准确
num_bins = 10
logbins = np.logspace(np.log10(Mass.min()), np.log10(Mass.max()), num_bins + 1)

# 绘制对数分箱直方图
n, bins, patches = plt.hist(x=Mass, bins=logbins, color='#0504aa', alpha=0.8, rwidth=0.85)

# --- 方法1:多项式拟合趋势线 ---
# 计算对数分箱的中点(用几何平均,适配对数刻度的特性)
bin_midpoints = np.sqrt(bins[:-1] * bins[1:])
# 在对数空间拟合多项式(避免大数值带来的拟合误差)
z = np.polyfit(np.log10(bin_midpoints), np.log10(n), 2)  # 2次多项式,可根据需求调整次数
p = np.poly1d(z)
# 生成拟合曲线的x轴点(更密集,让曲线更平滑)
fit_x = np.logspace(np.log10(Mass.min()), np.log10(Mass.max()), 100)
# 转换回原始空间的y值
fit_y = 10 ** p(np.log10(fit_x))
# 绘制拟合曲线
plt.plot(fit_x, fit_y, color='red', linewidth=2, label='Polynomial Fit Trend')

# --- 方法2:核密度估计(KDE)平滑曲线(可选,注释掉方法1即可用这个)---
# kde = gaussian_kde(np.log10(Mass))  # 在对数空间计算KDE,避免数值偏差
# kde_x = np.logspace(np.log10(Mass.min()), np.log10(Mass.max()), 100)
# # 缩放KDE值以匹配直方图的计数(KDE是概率密度,需乘以样本数和分箱宽度)
# kde_y = kde(np.log10(kde_x)) * len(Mass) * np.diff(np.log10(logbins))[0]
# plt.plot(kde_x, kde_y, color='green', linewidth=2, label='KDE Smooth Trend')

# 完善图表设置
plt.xscale('log')
plt.xlabel('Mass $(g)$ ')
plt.ylabel('Number of halos')
plt.legend()
plt.show()

关键细节说明:

  • 对数分箱优化:直接用Mass的最小/最大值生成对数分箱,比你原来先做线性分箱再转换的方式更贴合数据范围。
  • 分箱中点计算:用几何平均np.sqrt(bins[:-1] * bins[1:])作为对数分箱的中点,比线性中点更适配对数刻度的分布逻辑。
  • 拟合策略:在对数空间进行多项式拟合,避免原始数据的大数值导致拟合失效,之后再转换回原始空间绘制曲线。
  • KDE选项:如果想要更平滑的趋势线,可以用KDE方法,需要注意缩放KDE值来匹配直方图的计数单位(因为KDE默认是概率密度,不是计数)。

你可以根据自己的数据分布特点选择多项式拟合或者KDE方法,调整多项式次数或者KDE的带宽(gaussian_kde可以传入bw_method参数调整平滑程度)。

内容的提问来源于stack exchange,提问作者Salome

火山引擎 最新活动