Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate intersection between a line and a interpolation

Tags:

python

I want to calculate the intersection points between a line and a interpolation function. I can plot the interpolation as well the line in the figure:

import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate as scp

y = [ 815.97,  815.95,  815.98,  ...,  815.9] #60 elements
x = [405383892, 405383894, 405383895, ..., 405383896] #60 elements

mediana = np.median(x)
f = scp.interp1d(x,y,bounds_error=False,fill_value=0.,kind='cubic')
new_x_array = np.arange(min(x),max(x),0.01)
plt.figure()    
plt.plot(new_x_array,f(new_x_array),'r-')
plt.plot([x[0],x[59]], [mediana,mediana], 'g-')
plt.plot(x, y, 'mo')

Figure

But, I don't find the way to calculate the intersections points between the red function and the green line. What is the usual way to find an intersection between the two?

like image 735
Inaki Avatar asked Oct 23 '25 15:10

Inaki


2 Answers

interp1d does a spline interpolation between your data points. As far as I know, there is no method in scipy which gives you all roots on a domain for this interpolation, but because its spline interpolation you can solve this.

You can do the following.

  1. Reconstruct the spline polynoms on each subdomain with splev and friends, so you have the spline coefficients ==> coefficients of polynoms.
  2. With the polynoms on each subdomain you can reformulate your problem as an intersection of a polynom 2nd order (or what order you chose for interpolatint) on each subdomain and use a standard root finder for this (or use an analytical solution).
  3. Check if the roots are within the subdomain. If yes, you have found an intersection.

So for low spline order this should be straight forward.

like image 68
Bort Avatar answered Oct 26 '25 03:10

Bort


Thanks for the answer! I will use that solution in the future. Finally I solved it looking for the values close to the interpolation line:

index=[]
for pos in range(0,len(new_x_array)-1):
    if (mediana > f(new_x_array[pos])) & (mediana < f(new_x_array[pos+1])):
        index.append(new_x_array[pos])
    if (mediana < f(new_x_array[pos])) & (mediana > f(new_x_array[pos+1])):
        index.append(new_x_array[pos])

The index array takes the position close to the line.

like image 43
Inaki Avatar answered Oct 26 '25 04:10

Inaki



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!