2017-07-19 203 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}爲您想嘗試的每個比例值,然後查找最小值。