2017-07-19 197 views
1

我有一些数据,并且我已经绘制了对波长(蓝点)的大小。然后我有一些代码可以从文件中读取恒星模型,并将它绘制在同一个图上(粉红线)。在这段代码中,有一个可以调整的刻度,可以在图表上向上或向下移动这一行。到目前为止,我一直在改变比例尺,以便线条尽可能接近我的观点,但我想写一些代码来计算比例尺的值,从而得出我的点和该线是最小的。这是到目前为止我的代码:找到点与曲线之间最小距离的Python代码

#Import modules 

from math import * 
import numpy as np 
import matplotlib.pyplot as plt 

# Specify data 

wavelength = 
np.array([357.389,445.832,472.355,547.783,620.246,752.243,891.252,2164.089]) 
magnitude = 
np.array([24.0394,23.1925,23.1642,22.4794,21.7496,20.9047,20.4671,19.427]) 

# Create Graph 

#plt.scatter(wavelength, magnitude) 
#plt.ylim([25,18]) 
#plt.xlim([300,2200]) 
#plt.xlabel('wavelength (nm)') 
#plt.ylabel('magnitude') 
#plt.title('object 1') 
#plt.show() 
#plt.close() 

#now - here is some code that reads a model stellar population model from a 
file 

lines = open('fig7b.dat').readlines() 

wavelengths, luminosities = [],[] 

for l in lines: 
    s = l.split() 
    wl = s[0] 
    old = s[-1] 
    if '#' not in wl: 
     wavelengths.append(float(wl)) #wavelength in angstroms 
     luminosities.append(float(old)) #luminosities are in log units! 


scale = 3.5 
c=3.e8 
wavelengths = np.array(wavelengths) 
nus = c/(wavelengths*1.e-10) 
luminosities = np.array(luminosities) + scale 

luminosity_density = np.log10(((10**luminosities)*wavelengths)/nus) 

#plt.plot(wavelengths,luminosity_density) 
#z = 1.0 
#plt.plot(wavelengths*(1+z),luminosity_density,color='r') 

#plt.axis([900, 10000, 25,31]) 
#plt.savefig('sed.png') 
#plt.show() 
#plt.close() 

Mpc_to_cm = 3.086e24 #convert Mpc to cm 
z = 0.3448 #our chosen redshift 
D_L = 1841.7 * Mpc_to_cm 

#remember luminosity_density is logged at the moment 
flux_density = (10**luminosity_density) * (1+z)/(4*pi*D_L**2) #units will 
be erg/s/cm^2/Hz 

#now turn that into an AB magnitude - goes back to log 
AB_mag = -2.5*np.log10(flux_density) - 48.6 

#try plotting your photometry on here and play with z and D_L 
plt.plot(wavelengths*(1+z),AB_mag,color='pink') 
plt.scatter(wavelength*10., magnitude,color='cornflowerblue') 
plt.axis([900, 25000, 30,18]) 
plt.xlabel('wavelength') 
plt.ylabel('magnitude') 
plt.title('object 1') 
plt.savefig('sed_ab.png') 
plt.show() 

这使得看起来像这样的图表:

enter image description here

而且这将有助于打印最佳比例值。 我对python和编程一般都很陌生,粉红线不是一个简单的公式(在我给它的文件中有很多数据点),所以我一直有点卡住。如果我没有使用正确的语言来描述我的问题,并且对于长码 - 很多评论都是以前的情节,而我的主管在我分开的情节时保留了以前的情节,我抱歉。 (我用蟒2.7)

甲连结fig7b.dat:https://drive.google.com/open?id=0B_tOncLLEAYsbG8wcHJMYVowOXc

+0

您可以通过['scipy.optimize.minimize']将数据点的RMS计算为模型曲线并将其最小化(https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize .minimize.html)。也请看[适合度](https://en.wikipedia.org/wiki/Goodness_of_fit)。 –

+0

是否有机会获得'fig7b.dat'的副本? –

+0

@HughBothwell我已经在底部上传了一个链接! –

回答

1

首先,创建从曲线数据点的列表,使得每个点对应于点的第一列表(每个相应对点将具有相同的X坐标,即相同的波长)。

然后这两组点之间的最小距离将简单地为:(sum(points2)-sum(points1))/len(points1)

请看下面的例子

points1 = [1.1, 1.4, 1.8, 1.9, 2.3, 1.7, 1.9, 2.7] 
points2 = [8.4, 3.5, 2.9, 7.6, 0.1, 2.2, 3.3, 4.8] 

def min_distance(first,second): 
    assert len(first) == len(second) # must have same size 
    result = (sum(second) - sum(first))/len(first) 
    return result 

print("Adding this value to the first series of points") 
print("will provice minimum distance between curves") 
print(min_distance(points1,points2)) 

运行此WIL打印价值2.25。如果您将2.25添加到points1的所有值中,您将获得两组点之间的最小可能距离(在此特定情况下为62.36)。

在你的问题中,points1将是magnitude阵列。 points2将是来自fig7b.dat对应于波长的点。

这假定您想要最小化点与曲线之间的面积之和。它还假定距离是垂直测量的(这就是为什么您需要提取相应波长的点)。

1

如果你想编写自己的代码很少,而无需使用spicy.optimize我 建议:

使用您的理论频谱的内插在每个观测波长的评估理论值:

https://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html

如:

from scipy.interpolate import interp1d  
f2 = interp1d(wavelengths, luminosities, kind='cubic') 

比就可以计算出\ ^志{2}为您想尝试的每个比例值,然后查找最小值。