В настоящее время у меня есть набор данных, который выглядит следующим образом:
VP at melt(hPa) area (mm^2)
0.0557 4.52
0.0326 11.78
8.01e-3 6.13
1.35e-3 28.27
0.0432 8.17
9.86e-3 18.22
3.61e-5 75.43
1.90e-4 197.92
4.39e-3 69.39
2.46e-7 452
2.26e-5 452
5.85e-4 84.9
0.203 1
0.02 1
0.06 1
0.0274 30.5
3.17e-3 18.4
1.54 1
0.0342 26.05
10 1
7.32e-3 32.17
3.82e-3 50.26
Я пытаюсь найти соответствующее уравнение, чтобы соответствовать этим данным, чтобы служить общей линией тренда. В настоящее время пробовали экспоненциальное уравнение, которое выглядит следующим образом:
def l(x,a,b,c,d):
return a + b*np.exp(-c*np.log10(x) + d)
Однако это соответствие не является идеальным, как видно на графике ниже, я добавил кривую в красном и то, что я хочу от тренда линия для этих данных. https://i.stack.imgur.com/zKpPK.png (с = -6.97833911e + 00, b = 4.09785268e-06, c = 1.53739630e-01 и d = 1.43524303e + 01). Я также хотел бы sh игнорировать значения данных в подгонке, которые имеют значение yy 452. Это указывает на максимальное чтение.
Можно ли как-нибудь улучшить подгонку для этих данных? Должно ли уравнение быть изменено? Любое предложение приветствуется. Мой полный код показан ниже:
import numpy as np
import datetime
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import scipy.optimize as optimize
from scipy.optimize import curve_fit
vp1 = 1.1e1
vp0 = 1e-7
data_in=np.genfromtxt("Meltpool_Size.txt", skip_header=2, delimiter=" ", dtype=float)
melt = data_in[:,1] #meltpool size (mm)
vp = data_in[:,2] #vapor pressure
area = data_in[:,3]
target_size = str(data_in[:,4]) # recommended target size
# Try fitting the scatter plot to a line (act as a guideline)
data = np.array(list(zip(vp,melt,area)))
datasorted = np.array(sorted(data, key=lambda x: x[0]))
melt = datasorted[:,1] #meltpool size (mm)
vp = datasorted[:,0] #vapor pressure
area = datasorted[:,2] #meltpool area (ellipse) (mm^2)
data_trim = []
#IGNORE DATA WITH SECOND ENTRY = 452, AS THIS IS A MAXED OUT READING
for i in np.arange(0,len(datasorted)):
#if (datasorted[i,1] == 0.0):
# continue
if (datasorted[i,1] == 452.0):
continue
else:
data_trim.append(datasorted[i])
data_trim = np.array(data_trim)
#print(len(data_trim), len(datasorted))
vp_trim = data_trim[:,0]
melt_trim = data_trim[:,1]
print(vp_trim)
def l(x,a,b,c,d):
return a + b*np.exp(-c*np.log10(x) + d)
popt, pcov= curve_fit( l, vp_trim, melt_trim,p0 = [1, 0.1, 1, 40], maxfev= 10000)
print(popt)
fig=plt.figure(figsize=(4.5,3.6))
ax=fig.add_subplot(1,1,1)
ax.set_xlim([vp0, vp1])
ax.set_ylim([0.5,500])
ax.set_xscale("log", nonposy='clip')
ax.set_yscale("log", nonposy='clip')
ax.locator_params(axis='x', numticks=12)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.set_ylabel(r'Melt-Pool Area at 0.1\,Å/s ($mm^2$)')
ax.set_xlabel('Vapor Pressure at MP (hPa)')
ax.minorticks_on() # enable minor ticks
ax.set_axisbelow(True) # put grid behind curves
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=12)
ax.xaxis.set_minor_locator(locmin)
ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
#ax.grid(b = True, which = 'both',linewidth = 0.4, color= '#eeeeee')
ax.grid(b=True, which='minor', color='#eeeeee', linestyle='-', zorder=1, linewidth=0.4) # turn on major grid
ax.grid(b=True, which='minor', color='#f7f7f7', linestyle='-', zorder=1, linewidth=0.4) # turn on minor grid
ax.tick_params(direction='out', axis='both', which='both', pad=4)
ax.xaxis.set_ticks_position('bottom')
vprange = np.linspace(1e-7, 1e1, 100)
ax.plot(vprange, l(vprange,*popt), '--k',alpha = 0.5)
ax.scatter(vp,area,s = 3, color = 'black',zorder=2)
plt.savefig('meltpool.pdf', bbox_inches='tight', format='pdf')
plt.savefig('meltpool.png', dpi=300, bbox_inches='tight', format='png')