Important: For homework #3 it’s not mandatory that you fit the depth of your lines. This quick tutorial is meant to be informative for those who do decide to fit the depth of the Na I D lines.

Hey class 👋

I wanted to make a very quick tutorial on how to generally fit a curve with scipy

Let’s begin with three function models you’re given in this tutorial of a Gaussian, Lorentzian, and a Vogt profile:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

def G(x, alpha):
    """ Return Gaussian line shape at x with HWHM alpha """
    return np.sqrt(np.log(2) / np.pi) / alpha\\
                             * np.exp(-(x / alpha)**2 * np.log(2))

def L(x, gamma):
    """ Return Lorentzian line shape at x with HWHM gamma """
    return gamma / np.pi / (x**2 + gamma**2)

def V(x, alpha, gamma):
    """
    Return the Voigt line shape at x with Lorentzian component HWHM gamma
    and Gaussian component HWHM alpha.

    """
    sigma = alpha / np.sqrt(2 * np.log(2))

    return np.real(wofz((x + 1j*gamma)/sigma/np.sqrt(2))) / sigma\\
                                                           /np.sqrt(2*np.pi

Given these functions now, one thing we can do is fit these models to real data. This can be done using the curve_fit function from scipy. Here’s how it’s generally done:

Let’s say I have some random data (x,y) and I want do fit a Gaussian profile (i.e the G function from above). This is what my data looks like:

Screen Shot 2022-02-06 at 1.55.37 PM.png

To fit the data, I will use the scipy function curve_fit

from scipy.optimize import curve_fit

# NOTES: 
# 1) Remember that I decided to call my data variables: x, y 
# 2) curve_fit also takes uncertainties for the y-variable (i.e use sigma argument in the curve_fit function)
# 3) In curve_fit, I will pass in the following arguments: 
# Model (here I'm fitting my Gaussian function)
# x,y data
# bounds: i.e the boundary at which you want your parameter to vary
# bounds (for 2 parameters): ((min_param_1, min_param_2), (max_param_1, max_param_2))

# Optimize and fit data
best_fit, covariance = curve_fit(G, x, y, bounds=((-5, 0.1), (5, 3))

Cool, now we can plot the best_fit parameters to see what it looks like

plt.figure(figsize=(3,3))
plt.scatter(x, y, color='tomato')
plt.plot(x, G(x, *best_fit), color='k', lw=2)

Screen Shot 2022-02-06 at 2.01.16 PM.png