多个峰的 Python 数据拟合
Data Fitting in Python for multiple peaks
import numpy as np
from sympy.physics.wigner import wigner_6j
import matplotlib.pyplot as plt
xr=np.arange(0,33)
[Jo, Ju, I, Ao, Au]=[4.5, 4.5, 2.5,674.4,929]
Ao=Ao*0.00003335640954804
Au=Au*0.00003335640954804
xr1=100000000/np.array(xr)
positions=xr1
centroid = positions.mean(axis=0)
newo=0.005+100000000/4715.2274
Fo=[]
Fu=[]
new=[]
In=[]
Fomax=Jo+I
Fomin=abs(Jo-I)
Fumax=Ju+I
Fumin=abs(Ju-I)
no=int(2*min(Jo,I)+1)
for i in range(0,no):
Fo.append(Fomax-i)
nu=int(2*min(Ju,I)+1)
for i in range(0,nu):
Fu.append(Fumax-i)
for i in range(0,no):
for j in range(0,nu):
if abs(Fo[i]-Fu[j])<2:
new.append(newo+(Ao/2)*(Fo[i]*(Fo[i]+1)-Jo*(Jo+1)-I*(I+1))-(Au/2)*(Fu[j]*(Fu[j]+1)-Ju*(Ju+1)-I*(I+1)))
In.append((2*Fo[i]+1)*(2*Fu[j]+1)*(wigner_6j(Jo,Fo[i],I,Fu[j],Ju,1))**2/(2*I+1))
max1=np.max(In)
for i in range(0,len(new)):
for j in range(0,len(new)):
if new[i]>new[j]:
temp=new[j]
new[j]=new[i]
new[i]=temp
temp=In[j]
In[j]=In[i]
In[i]=temp
zr=[]
sigma=0.031
x2=[]
y2=[]
y2r=[]
for i in range(0, len(new)):
mew=new[i]
for j in range(-100,100):
c=mew+j/1000
cc=In[i]*(1/(sigma*(44/7)**0.5))*np.exp(-1*((c-mew)/sigma)**2)
y2.append(cc)
x2.append(c)
max2=np.max(y2)
for i in range(0,len(new)):
In[i]=In[i]/max1
for i in range(0,len(y2)):
y2[i]=y2[i]/max2
for i in range(0,len(y2)):
y2r.append(y2[i])
for i in range(0,15):
a=5
print(centroid)
fig, ax = plt.subplots()
plt.plot(x2, y2r,label="fitted data")
plt.legend()
plt.show()
我有这段代码,它产生了多个峰值。图 1 显示了具有多个相互重叠的峰的数据,但我试图通过使用这些重叠的峰来实现只有一条曲线,如图 2 中 'red' 行所示。
但问题是必须像最后一张图那样拟合一条线
我希望我现在明白了问题。如果我没看错,问题基本上是 x
值不同。最重要的是,所有内容都合并到一个列表中。为了处理这个问题,我将 print(centroid)
之后的所有内容都更改为
from scipy.interpolate import interp1d
def partition( inList, n ):
return zip( *[ iter( inList ) ] * n )
xSplit = partition( x2, 200 ) ###manually set to 200 as data is created with range(-100,100)
ySplit = partition( y2r, 200 )
allx = sorted( x2 )
ally = np.zeros( len( allx ), np.float )
funcDict = dict()
for i in range( len( xSplit ) ):
funcDict[i] = interp1d( xSplit[i], ySplit[i], kind='linear', bounds_error=False, fill_value=0 )
for i in range( len( xSplit ) ):
ally += funcDict[i]( allx )
fig, ax = plt.subplots()
ax.plot( allx, ally, linewidth=2 )
for col1, col2 in zip( xSplit, ySplit ):
plt.plot( col1, col2, linestyle='--' )
plt.legend()
plt.show()
这给了你
这是总和,但使用了数据插值。是这个主意吗?
编辑
似乎 OP 需要更多的信封而不是总和。 James Phillips 给出了解决方案。甚至可以使用 numpy 更改
来缩短它
ally += funcDict[i]( allx )
到
ally = np.maximum(ally, funcDict[i]( allx ) )
然后给出
将@mikuszefski 代码与此代码相结合以获得最大值可能是您正在寻找的,要使用它,请将 "print(centroid)" 之后的所有内容替换为:
from scipy.interpolate import interp1d
def partition( inList, n ):
return zip( *[ iter( inList ) ] * n )
xSplit = partition( x2, 200 ) ###manually set to 200 as data is created with range(-100,100)
ySplit = partition( y2r, 200 )
allx = sorted( x2 )
ally = np.zeros( len( allx ), np.float )
funcDict = dict();xSplit = list(xSplit);ySplit = list(ySplit)
for i in range( len( xSplit ) ):
funcDict[i] = interp1d( xSplit[i], ySplit[i], kind='linear', bounds_error=False, fill_value=0 )
for i in range( len( xSplit ) ):
for j in range(len(allx)):
ally[j] = max(ally[j],funcDict[i](allx[j]))
fig, ax = plt.subplots()
ax.plot( allx, ally, linewidth=2 )
for col1, col2 in zip( xSplit, ySplit ):
plt.plot( col1, col2, linestyle='--' )
plt.legend()
plt.show()
import numpy as np
from sympy.physics.wigner import wigner_6j
import matplotlib.pyplot as plt
xr=np.arange(0,33)
[Jo, Ju, I, Ao, Au]=[4.5, 4.5, 2.5,674.4,929]
Ao=Ao*0.00003335640954804
Au=Au*0.00003335640954804
xr1=100000000/np.array(xr)
positions=xr1
centroid = positions.mean(axis=0)
newo=0.005+100000000/4715.2274
Fo=[]
Fu=[]
new=[]
In=[]
Fomax=Jo+I
Fomin=abs(Jo-I)
Fumax=Ju+I
Fumin=abs(Ju-I)
no=int(2*min(Jo,I)+1)
for i in range(0,no):
Fo.append(Fomax-i)
nu=int(2*min(Ju,I)+1)
for i in range(0,nu):
Fu.append(Fumax-i)
for i in range(0,no):
for j in range(0,nu):
if abs(Fo[i]-Fu[j])<2:
new.append(newo+(Ao/2)*(Fo[i]*(Fo[i]+1)-Jo*(Jo+1)-I*(I+1))-(Au/2)*(Fu[j]*(Fu[j]+1)-Ju*(Ju+1)-I*(I+1)))
In.append((2*Fo[i]+1)*(2*Fu[j]+1)*(wigner_6j(Jo,Fo[i],I,Fu[j],Ju,1))**2/(2*I+1))
max1=np.max(In)
for i in range(0,len(new)):
for j in range(0,len(new)):
if new[i]>new[j]:
temp=new[j]
new[j]=new[i]
new[i]=temp
temp=In[j]
In[j]=In[i]
In[i]=temp
zr=[]
sigma=0.031
x2=[]
y2=[]
y2r=[]
for i in range(0, len(new)):
mew=new[i]
for j in range(-100,100):
c=mew+j/1000
cc=In[i]*(1/(sigma*(44/7)**0.5))*np.exp(-1*((c-mew)/sigma)**2)
y2.append(cc)
x2.append(c)
max2=np.max(y2)
for i in range(0,len(new)):
In[i]=In[i]/max1
for i in range(0,len(y2)):
y2[i]=y2[i]/max2
for i in range(0,len(y2)):
y2r.append(y2[i])
for i in range(0,15):
a=5
print(centroid)
fig, ax = plt.subplots()
plt.plot(x2, y2r,label="fitted data")
plt.legend()
plt.show()
我有这段代码,它产生了多个峰值。图 1 显示了具有多个相互重叠的峰的数据,但我试图通过使用这些重叠的峰来实现只有一条曲线,如图 2 中 'red' 行所示。
但问题是必须像最后一张图那样拟合一条线
我希望我现在明白了问题。如果我没看错,问题基本上是 x
值不同。最重要的是,所有内容都合并到一个列表中。为了处理这个问题,我将 print(centroid)
之后的所有内容都更改为
from scipy.interpolate import interp1d
def partition( inList, n ):
return zip( *[ iter( inList ) ] * n )
xSplit = partition( x2, 200 ) ###manually set to 200 as data is created with range(-100,100)
ySplit = partition( y2r, 200 )
allx = sorted( x2 )
ally = np.zeros( len( allx ), np.float )
funcDict = dict()
for i in range( len( xSplit ) ):
funcDict[i] = interp1d( xSplit[i], ySplit[i], kind='linear', bounds_error=False, fill_value=0 )
for i in range( len( xSplit ) ):
ally += funcDict[i]( allx )
fig, ax = plt.subplots()
ax.plot( allx, ally, linewidth=2 )
for col1, col2 in zip( xSplit, ySplit ):
plt.plot( col1, col2, linestyle='--' )
plt.legend()
plt.show()
这给了你
这是总和,但使用了数据插值。是这个主意吗?
编辑 似乎 OP 需要更多的信封而不是总和。 James Phillips 给出了解决方案。甚至可以使用 numpy 更改
来缩短它ally += funcDict[i]( allx )
到
ally = np.maximum(ally, funcDict[i]( allx ) )
然后给出
将@mikuszefski 代码与此代码相结合以获得最大值可能是您正在寻找的,要使用它,请将 "print(centroid)" 之后的所有内容替换为:
from scipy.interpolate import interp1d
def partition( inList, n ):
return zip( *[ iter( inList ) ] * n )
xSplit = partition( x2, 200 ) ###manually set to 200 as data is created with range(-100,100)
ySplit = partition( y2r, 200 )
allx = sorted( x2 )
ally = np.zeros( len( allx ), np.float )
funcDict = dict();xSplit = list(xSplit);ySplit = list(ySplit)
for i in range( len( xSplit ) ):
funcDict[i] = interp1d( xSplit[i], ySplit[i], kind='linear', bounds_error=False, fill_value=0 )
for i in range( len( xSplit ) ):
for j in range(len(allx)):
ally[j] = max(ally[j],funcDict[i](allx[j]))
fig, ax = plt.subplots()
ax.plot( allx, ally, linewidth=2 )
for col1, col2 in zip( xSplit, ySplit ):
plt.plot( col1, col2, linestyle='--' )
plt.legend()
plt.show()