Python代码,用于查找点与曲线之间的最小距离

时间:2017-07-19 00:55:34

标签: python python-2.7 matplotlib plot distance

我有一些数据,我已经绘制了针对波长的幅度(蓝点)。然后,我有一些代码从文件中读取模型恒星,并在同一图表(粉红色线)上绘制。在此代码中,有一个可以调整的比例,可以在图表上向上或向下移动此行。到目前为止,我一直在改变比例,以便线条尽可能接近我的观点,但是我想编写一些代码来计算我的点与总点距离的比例值。这条线是最小的。到目前为止,这是我的代码:

#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和编程很新,粉色线不是简单的等式(在我给它的文件中由很多数据点组成)所以我得到了一点点卡住。如果我没有使用正确的语言来描述我的问题,并且对于长代码,我很抱歉 - 很多评论都是我以前的情节,我的主管在我有单独的情节之前保留了这些情节。 (我使用的是python 2.7)

指向fig7b.dat的链接:https://drive.google.com/open?id=0B_tOncLLEAYsbG8wcHJMYVowOXc

2 个答案:

答案 0 :(得分: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 :(得分:1)

如果你想编写自己的小代码而不使用spicy.optimize我 会建议:

使用理论光谱的插值来评估每个观察波长的理论值:

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

e.g:

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

您可以为想要尝试的每个比例值计算\ chi ^ {2},然后找到最小值。