I'm trying to create an average trace line/best fit line for multiple noisy sine waves. This is the code I've generated to create the sine waves:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import leastsq
x = np.arange(0,10,.05)
noise = np.random.normal(0,.05,200)
wave = np.sin(x)
y = noise + wave
noise2 = np.random.normal(0,.05,200)
y2 = noise2 + wave
noise3 = np.random.normal(0,.05,200)
y3 = noise3 + wave
plt.plot(x, y)
plt.plot(x, y2)
plt.plot(x, y3)
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.show()
The problem I'm having when I search online/this site for advice is that most people are creating best fit lines for a group of data points, not multiple lines.
Any advice would be appreciated, thanks!
This is what I've tried so far:
guess_mean = np.mean(y)
guess_std = 3.0*np.std(y)/(2**.5)
guess_phase = 0
first_guess= guess_std*np.sin(x+guess_phase) + guess_mean
plt.plot(first_guess, label='first guess')
but this isn't working, I think its because the periods are off.
There are several ways to do so. Here is what I think is the simplest to implement.
First, let's define a function that takes a tuple
(a, b, c)
, and finds the sum of the fits of a * sin(b * x + c) to each ofy, y1, y2
.With that, we can call
scipy.optimize
:For a sanity check, try the solution (
[ 0.99811506, -1.00102866, 3.14393633]
):Vs. the noisy data: