title: Using scipy to fit a damped sine wave to data
body: <p>In my experimental project I have a droplet vibrating which acts a damped simple harmonic oscillator. I have to fit a damped sine wave onto the data to try and extract variables such as the frequency of the vibration. However I am having a bit of trouble perfecting the curve fitting. Below is the code that I am using:</p>
  <pre><code>import numpy as np
  import imageio
  import os
  import cv2 as cv
  import matplotlib.pyplot as plt
  from fractions import Fraction
  from scipy.optimize import curve_fit
  import tkinter as tk
  from tkinter import filedialog
  
  # %% Curve fitting
  
  root = tk.Tk(); root.withdraw()  # close the tkinter root window
  
  file_path = filedialog.askopenfilename()  # open file dialogue box
  
  data=np.loadtxt(file_path, skiprows=0)  # read the data from file
  time = data[:, 0]; height = data[:, 1]  # extract the time and data arrays
  
  
  def myfit(t, a, b, c, phi, ho):                 # define the function
      return a*np.exp(b*t)*np.cos(c*t+phi) + ho
  
  
  # perform the fit # [1,-10,100,0,2]
  param, param_cov = curve_fit(myfit, time, height, maxfev=2500)
  
  # get the standard deviations of all fit parameters from variance-co-variance matrix
  stdevm = np.sqrt(np.diag(param_cov))
  
  # generate the fit line ready for plotting
  fitplot = param[0]*np.exp(param[1]*time)*np.cos(param[2]*time+param[3])+param[4]
  
  plt.figure();plt.plot(time,height,'r.',label=&quot;data&quot;)
  plt.plot(time,fitplot,'-', color ='blue', label =&quot;fit&quot;)
  plt.legend();plt.xlabel(&quot;time (seconds)&quot;);plt.ylabel(&quot;droplet height (mm)&quot;)
  </code></pre>
  <p>However this does no produce a very good fit. Despite the jaggedness which is expected considering the number of points the value of b is positive when it should be negative. The following graph is produced from the code above:</p>
  <p><a href="https://i.stack.imgur.com/tXIxA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/tXIxA.png" alt="Damped sine wave fitted" /></a></p>
  <p>In order to rectify this I tried rectifying the bounds as such:</p>
  <pre><code>param, param_cov = curve_fit(myfit, time, height, p0=[6, 10, 471, 1, 2], bounds=[[4, -50, 100, -10, -2], [7, 0, 1000, 10, 1]], maxfev=2500)
  </code></pre>
  <p>However the error below gets produced:</p>
  <p><a href="https://i.stack.imgur.com/DEJhR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DEJhR.png" alt="error shown when bounds change" /></a></p>
  <p>I need help trying to either fixing the bounds, or is there another better way of fitting this data. Thanks in advance, any help is much appreciated.</p>