Python - matplotlib: найти пересечение линейных участков - PullRequest
14 голосов
/ 11 ноября 2011

У меня, наверное, простой вопрос, который заставляет меня уже некоторое время молчать. Есть ли простой способ вернуть пересечение двух построенных (не аналитических) наборов данных в python matplotlib?

Для уточнения у меня есть что-то вроде этого:

x=[1.4,2.1,3,5.9,8,9,23]
y=[2.3,3.1,1,3.9,8,9,11]
x1=[1,2,3,4,6,8,9]
y1=[4,12,7,1,6.3,8.5,12]
plot(x1,y1,'k-',x,y,'b-')

Данные в этом примере полностью произвольны. Теперь я хотел бы знать, есть ли простая встроенная функция, которую я постоянно пропускаю, которая возвращает мне точные пересечения между двумя графиками.

Надеюсь, я дал понять, а также, что я не пропустил что-то совершенно очевидное ...

1 Ответ

24 голосов
/ 11 ноября 2011

Мы могли бы использовать scipy.interpolate.PiecewisePolynomial для создания функций, которые определяются вашими кусочно-линейными данными.

p1=interpolate.PiecewisePolynomial(x1,y1[:,np.newaxis])
p2=interpolate.PiecewisePolynomial(x2,y2[:,np.newaxis])

Мы могли бы тогда взять разницу этих двух функций,

def pdiff(x):
    return p1(x)-p2(x)

и используйте optimize.fsolve , чтобы найти корни pdiff:

import scipy.interpolate as interpolate
import scipy.optimize as optimize
import numpy as np

x1=np.array([1.4,2.1,3,5.9,8,9,23])
y1=np.array([2.3,3.1,1,3.9,8,9,11])
x2=np.array([1,2,3,4,6,8,9])
y2=np.array([4,12,7,1,6.3,8.5,12])    

p1=interpolate.PiecewisePolynomial(x1,y1[:,np.newaxis])
p2=interpolate.PiecewisePolynomial(x2,y2[:,np.newaxis])

def pdiff(x):
    return p1(x)-p2(x)

xs=np.r_[x1,x2]
xs.sort()
x_min=xs.min()
x_max=xs.max()
x_mid=xs[:-1]+np.diff(xs)/2
roots=set()
for val in x_mid:
    root,infodict,ier,mesg = optimize.fsolve(pdiff,val,full_output=True)
    # ier==1 indicates a root has been found
    if ier==1 and x_min<root<x_max:
        roots.add(root[0])
roots=list(roots)        
print(np.column_stack((roots,p1(roots),p2(roots))))

выходы

[[ 3.85714286  1.85714286  1.85714286]
 [ 4.60606061  2.60606061  2.60606061]]

Первый столбец - это значение x, второй столбец - это значение y первого PiecewisePolynomial, оцененного в x, а третий столбец - значение y для второго PiecewisePolynomial.

...