You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用lmfit拟合直方图洛伦兹曲线时遇维度不匹配错误求助

问题根源与修正方案

报错的核心是拟合时x和y的维度不匹配:

  • plt.hist返回的bins是包含41个元素的边缘数组(因为你设了bins=40,边缘数= bins数+1)
  • 而n是每个bin的计数,只有40个元素
  • 你用bins[1:](41个元素)作为拟合的x,和n(40个元素)的y维度不一致,导致报错

另外,拟合直方图应该用bin的中心位置作为x轴数据,而不是bin的右边缘,这样拟合结果更合理。

修正后的代码

from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np
from lmfit.models import LorentzianModel
import csv

data_initial = list()
data_floats = list()

# 读取数据
with open('pendumlum_data.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in spamreader:
        data_initial.append(','.join(row))

for x in data_initial[1:]:
    y = float(x)
    data_floats.append(y)

# 统计与数据筛选
mu, std = norm.fit(data_floats)
data = [x for x in data_floats if (mu - 2*std) < x < (mu + 2*std)]

bins = 40
n, bins, patches = plt.hist(data, bins=bins, range=(mu-2*std, mu+2*std), 
                            facecolor='green', edgecolor='black', alpha=0.6)

# 计算bin中心(关键修改1:用中心作为拟合x值)
bincenters = 0.5 * (bins[1:] + bins[:-1])

# 初始化洛伦兹模型
mod = LorentzianModel()
# 初始参数优化:amplitude设为n的峰值,center用mu,sigma用std
pars = mod.make_params(amplitude=np.max(n), center=mu, sigma=std)

# 关键修改2:用bincenters作为x,和n维度匹配(都是40个元素)
fit = mod.fit(n, pars, x=bincenters)
print(fit.fit_report(min_correl=0.25))

# 生成平滑x轴用于绘制拟合曲线
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
# 用拟合模型计算平滑曲线的y值
fit_y = fit.eval(x=x)

# 绘制误差棒和拟合曲线
plt.errorbar(bincenters, n, yerr=np.sqrt(n), linestyle='None', fmt='.k')
plt.plot(x, fit_y, '--r', label='Lorentzian Fit')

# 更新拟合信息文本(用实际拟合结果)
plt.text(10, 36, f'Fitted Mean: {fit.params["center"].value:.3f} +/- {fit.params["center"].stderr:.3f}')
plt.text(10, 34, f'Fitted Std: {fit.params["sigma"].value:.3f} +/- {fit.params["sigma"].stderr:.3f}')
plt.text(10, 32, f'Chi2/ndf: {fit.chisqr/fit.ndf:.3f}')

plt.xlabel('g (m/s^2)')
plt.ylabel('Counts')
plt.title(r'Pendulum Data')
plt.legend()

plt.subplots_adjust(left=0.15)
plt.show()

额外说明

  1. 用列表推导式简化了数据筛选代码,更简洁易读
  2. 拟合时用bincenters作为x,和n的维度完全匹配(都是40),彻底解决维度不匹配的报错
  3. 绘制拟合曲线时,用fit.eval(x=x)生成平滑曲线,避免直接使用fit对象导致的绘图错误
  4. 把固定的拟合文本换成了实际拟合结果的参数值和误差,输出信息更准确

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:01:12