【问题标题】:How to find the intersection points between two plotted curves in matplotlib?如何在 matplotlib 中找到两条绘制曲线之间的交点?
【发布时间】:2020-03-25 17:58:03
【问题描述】:

我想找到两条曲线的交点。例如下面。 可以有多个交点。现在我正在通过查找x,y 坐标之间的距离来查找交点。但是,如您在图中看到的那样,当交点介于(17-18 x 轴)之间时,这种方法有时不能给出准确的点。

我需要从曲线中获取所有点来解决这个问题。有什么方法可以全部获取吗?

【问题讨论】:

    标签: python matplotlib curve


    【解决方案1】:

    这是我的方法。我首先创建了两条测试曲线,仅使用 12 个样本点,只是为了说明这个概念。使用样本点创建数组后,曲线的精确方程将丢失。

    然后,搜索两条曲线之间的交点。通过逐点遍历数组,并检查一条曲线何时从另一条曲线下方到上方(或相反),可以通过求解线性方程来计算交点。

    然后绘制交点以直观地检查结果。

    import numpy as np
    from matplotlib import pyplot as plt
    
    N = 12
    t = np.linspace(0, 50, N)
    curve1 = np.sin(t*.08+1.4)*np.random.uniform(0.5, 0.9) + 1
    curve2 = -np.cos(t*.07+.1)*np.random.uniform(0.7, 1.0) + 1
    # note that from now on, we don't have the exact formula of the curves, as we didn't save the random numbers
    # we only have the points correspondent to the given t values
    
    fig, ax = plt.subplots()
    ax.plot(t, curve1,'b-')
    ax.plot(t, curve1,'bo')
    ax.plot(t, curve2,'r-')
    ax.plot(t, curve2,'ro')
    
    intersections = []
    prev_dif = 0
    t0, prev_c1, prev_c2 = None, None, None
    for t1, c1, c2 in zip(t, curve1, curve2):
        new_dif = c2 - c1
        if np.abs(new_dif) < 1e-12: # found an exact zero, this is very unprobable
            intersections.append((t1, c1))
        elif new_dif * prev_dif < 0:  # the function changed signs between this point and the previous
            # do a linear interpolation to find the t between t0 and t1 where the curves would be equal
            # this is the intersection between the line [(t0, prev_c1), (t1, c1)] and the line [(t0, prev_c2), (t1, c2)]
            # because of the sign change, we know that there is an intersection between t0 and t1
            denom = prev_dif - new_dif
            intersections.append(((-new_dif*t0  + prev_dif*t1) / denom, (c1*prev_c2 - c2*prev_c1) / denom))
        t0, prev_c1, prev_c2, prev_dif = t1, c1, c2, new_dif
    print(intersections)
    
    ax.plot(*zip(*intersections), 'go', alpha=0.7, ms=10)
    plt.show()
    

    【讨论】:

    • 很好的答案!不错的方法。
    【解决方案2】:

    曲线只是连接每个点的一系列直线。因此,如果你想增加点的数量,你可以简单地在每对点之间做一个线性外推:

    x1,x2 = 17,20
    y1,y2 = 1,5
    
    N = 20
    x_vals = np.linspace(x1,x2,N)
    y_vals = y1+(x_vals-x1)*((y2-y1)/(x2-x1))
    
    fig, ax = plt.subplots()
    ax.plot([x1,x2],[y1,y2],'k-')
    ax.plot(x_vals,y_vals, 'ro')
    

    【讨论】:

    • 但是如何为整体做到这一点。通过取两个连续点并附加点?
    • 如果你想对整条曲线都这样,那不妨使用numpy的线性插值法docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html
    • 我没有曲线方程,我得到了两个列表中每条曲线的 x,y 坐标。
    • 你不需要方程,否则有什么意义?从上面的链接中,您有两个数组 x 和 y 用于在 xvals 处插入 y 的值
    猜你喜欢
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多