# Multiple curve fitting python

I have this 7 quasi-lorentzian curves which are fitted to my data. and I would like to join them, to make one connected curved line. Do You have any ideas how to do this? I've read about ComposingModel at lmfit documentation, but it's not clear how to do this.

Here is a sample of my code of two fitted curves.

for dataset in [Bxfft]:
dataset = np.asarray(dataset)
freqs, psd = signal.welch(dataset, fs=266336/300, window='hamming', nperseg=16192, scaling='spectrum')
plt.semilogy(freqs[0:-7000], psd[0:-7000]/dataset.size**0, color='r', label='Bx')
x = freqs[100:-7900]
y = psd[100:-7900]

# 8 Hz
model = Model(lorentzian)
params = model.make_params(amp=6, cen=5, sig=1, e=0)
result = model.fit(y, params, x=x)
final_fit = result.best_fit
print "8 Hz mode"
print(result.fit_report(min_correl=0.25))
plt.plot(x, final_fit, 'k-', linewidth=2)

# 14 Hz
x2 = freqs[220:-7780]
y2 = psd[220:-7780]

model2 = Model(lorentzian)
pars2 = model2.make_params(amp=6, cen=10, sig=3, e=0)
pars2['amp'].value = 6
result2 = model2.fit(y2, pars2, x=x2)
final_fit2 = result2.best_fit
print "14 Hz mode"
print(result2.fit_report(min_correl=0.25))
plt.plot(x2, final_fit2, 'k-', linewidth=2)


What I desire is something like this. • I have an example of fitting a double Lorentzian peak equation to Raman spectroscopy of carbon nanotubes at bitbucket.org/zunzuncode/RamanSpectroscopyFit -that might be a useful starting point for you to build on as the problem is somewhat similar. – James Phillips Jun 1 '18 at 19:23
• Thanks for uploading, well it's quite useful, but my problem is that for every curve I change my initial x (which is data), and looking at your example there are two lorentzians, but they are based on the same sample of data. – Hiddenguy Jun 1 '18 at 20:02

That pretty much solved my problem.

    x = freqs[100:-7240]
y = psd[100:-7240]

peak1 = Model(lorentzian, prefix='p1_')
peak2 = Model(lorentzian, prefix='p2_')
peak3 = Model(lorentzian, prefix='p3_')
peak4 = Model(lorentzian, prefix='p4_')
peak5 = Model(lorentzian, prefix='p5_')
peak6 = Model(lorentzian, prefix='p6_')
peak7 = Model(lorentzian, prefix='p7_')

# make composite by adding (or multiplying, etc) components
model = peak1 + peak2 + peak3 + peak4 + peak5 + peak6 + peak7

# make parameters for the full model, setting initial values
# using the prefixes
params = model.make_params(p1_amp=6, p1_cen=8, p1_sig=1, p1_e=0,
p2_amp=16, p2_cen=14, p2_sig=3, p2_e=0,
p3_amp=16, p3_cen=21, p3_sig=3, p3_e=0,
p4_amp=16, p4_cen=28, p4_sig=3, p4_e=0,
p5_amp=16, p5_cen=33, p5_sig=3, p5_e=0,
p6_amp=16, p6_cen=39, p6_sig=3, p6_e=0,
p7_amp=16, p7_cen=45, p7_sig=3, p7_e=0)

# then do a fit over the full data range
result = model.fit(y, params, x=x)
final = result.best_fit
print(result.fit_report())
plt.plot(x, final, 'k-', linewidth=2)
plt.show()

• Sometime you can get a better fit by adding an offset parameter - that might be useful in the future. – James Phillips Jun 4 '18 at 1:22