How to find the points of intersection of a line and multiple curves in Python?

后端 未结 1 2011
终归单人心
终归单人心 2020-12-28 10:09

I have data represented in the figure.

\"enter

The curves were extrapolated an

相关标签:
1条回答
  • 2020-12-28 10:38

    We do know the equations of the curves. They are of the form a*x**2 + b*x + c, where a,b, and c are the elements of the vector returned by np.polyfit. Then we just need to find the roots of a quadratic equation in order to find the intersections:

    def quadratic_intersections(p, q):
        """Given two quadratics p and q, determines the points of intersection"""
        x = np.roots(np.asarray(p) - np.asarray(q))
        y = np.polyval(p, x)
        return x, y
    

    The above function isn't super robust: there doesn't need to be a real root, and it doesn't really check for that. You're free to make it better.

    Anyways, we give quadratic_intersections two quadratics, and it returns the two points of intersection. Putting it into your code, we have:

    x1 = np.linspace(0, 0.4, 100)
    y1 = -100 * x1 + 100
    plt.figure(figsize = (7,7))
    plt.subplot(111)
    
    plt.plot(x1, y1, linestyle = '-.', linewidth = 0.5, color =  'black')
    for i in range(5):
        x_val = np.linspace(x[0, i] - 0.05, x[-1, i] + 0.05, 100)
        poly = np.polyfit(x[:, i], y[:, i], deg=2)
        y_int  = np.polyval(poly, x_val)
        plt.plot(x[:, i], y[:, i], linestyle = '', marker = 'o')
        plt.plot(x_val, y_int, linestyle = ':', linewidth = 0.25, color =  'black')
        ix = quadratic_intersections(poly, [0, -100, 100])
        plt.scatter(*ix, marker='x', color='black', s=40, linewidth=2)
    
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.xlim([0,.35])
    plt.ylim([40,110])
    plt.show()
    

    This makes the following figure:

    enter image description here

    Now, if you don't know that the functions you are dealing with are polynomials, you can use the optimization tools in scipy.optimize to find the root. For example:

    import scipy.optimize
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.style
    
    matplotlib.style.use('fivethirtyeight')
    %matplotlib inline
    
    f = lambda x: np.cos(x) - x
    g = np.sin
    
    h = lambda x: f(x) - g(x)
    
    x = np.linspace(0,3,100)
    plt.plot(x, f(x), zorder=1)
    plt.plot(x, g(x), zorder=1)
    
    x_int = scipy.optimize.fsolve(h, 1.0)
    y_int = f(x_int)
    
    plt.scatter(x_int, y_int, marker='x', s=150, zorder=2, 
                linewidth=2, color='black')
    
    plt.xlim([0,3])
    plt.ylim([-4,2])
    

    Which plots:

    enter image description here

    0 讨论(0)
提交回复
热议问题