Smoothing A Curve With Many Peaks With Gaussian
I have spectroscopy data with some very sharp peaks as seen in blue curve. I would like to make the peaks a bit more smooth like the orange curve in the plot. I thought the easies
Solution 1:
Looks like you want a "kernel density estimator" which is implemented by:
from scipy.stats import gaussian_kde
X = np.random.rand(50) * 3500
Y = np.random.rand(50) * 50
xi = linspace(0, 3500, 1000)
kde = gaussian_kde(X, weights = Y, bw_method = .01) #tune `bw_method` to get the bandwidth you want
plt.plot(xi, kde.pdf(xi))
You may also need to adjust the y
scaling of the graph to match your requirements
Solution 2:
This is manually reproducing the orange curve given in the OP. Turns out it is convoluted with a Lorentzian not Gaussian.
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import find_peaks
from scipy.optimize import curve_fit
defgs( x, x0, a, s ):
return a * np.exp( -( x - x0 )**2 / ( 2 * s**2 ) )
defcs( x, x0, a, s ):
return a / ( ( x - x0 )**2 + s**2 )
conrange = 40000### gasiian is no good# ~condata = np.fromiter( ( gs(x, 0, 1, 1800 ) for x in np.arange( -5000, 5000 ) ), np.float )### Cauchy looks much better
condata = np.fromiter(
(
cs( x, 0, 1, 2000 ) for x in np.arange( -conrange, conrange )
), np.float
)
### shift can be zero. ### Amplitude does not matter as it will be scaled later anyway### width matters of course, but is adjusted manually for the moment.
data = np.loadtxt("ir_data.txt")
xdata = data[:, 0]
ydata = data[:, 1]
xdataint = np.fromiter( ( int( x* 100 ) for x in xdata ), int )
xmin = xdataint[0]
xmax = xdataint[-1]
xfilled = np.arange( xmin , xdataint[-1] + 1 )
yfilled = np.zeros( len( xfilled ), dtype=np.float )
xfloat = np.fromiter( ( x / 100.for x in xfilled), float )
for x, y inzip( xdataint, ydata ):
yfilled[ x - xmin ] = y
### just putting a manual scale here, but the real one can be calculated### from the convolution properties
yc = 1e6 * np.convolve( condata, yfilled, mode="full" )
xfull = np.arange(
-conrange + xmin, xmin + conrange + len( xfilled ) - 1
)
xfloat = np.fromiter( ( 0.01 * x for x in xfull ), float )
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
ax.plot( xdata, ydata, ls='', marker='o', ms=2 )
ax.plot( xfloat, yc, ls='-')
plt.show()
Disclaimer
This are preliminary results and only posted due to request from the author of the OP. The might be some refinement.
Post a Comment for "Smoothing A Curve With Many Peaks With Gaussian"