问题描述
我有一些光谱数据,如蓝色曲线所示,有一些非常尖锐的峰.我想使峰更平滑,如图中的橙色曲线.
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.
我认为最简单的方法是将我的数据点与高斯进行卷积.我知道 numpy
和 scipy
都具有 convolve
函数,但是我不确定是否需要一维或二维卷积才能得到所需的内容.到目前为止,我尝试了 scipy
的 convolve1d
和 gaussian_filter1d
和 numpy
的 convolve
.他们都没有改善连接数据点的尖锐线条.我也不知道如何选择正确的sigma或权重...
I thought the easiest way to do this is to convolve my data points with Gaussians. I know both numpy
and scipy
have convolve
functions but I am not sure if I need 1D or 2D convolution to get what I need. So far I tried convolve1d
and gaussian_filter1d
from scipy
and convolve
from numpy
. None of them improved the sharp lines connecting the data points. I also don't know how to choose the correct sigma or weights...
包含数据点的文本文件是此处
The text file containing the data points is here.
橙色曲线是从可视化程序生成的,我希望能够使用 python
而不是使用该程序自行生成.
The orange curve is generated from a visualisation programme and I wish to be able to generate it myself with python
rather than using the programme.
推荐答案
这是手动再现OP中给出的橙色曲线的方法.事实证明,它是用洛伦兹式而不是高斯式计算的.
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
def gs( x, x0, a, s ):
return a * np.exp( -( x - x0 )**2 / ( 2 * s**2 ) )
def cs( 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 in zip( 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()
免责声明
这是初步结果,仅应OP作者的要求发布.可能有一些改进.
This are preliminary results and only posted due to request from the author of the OP. The might be some refinement.
这篇关于使用高斯平滑多峰曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!