Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 延长线路以与另一条线路平滑连接_Python_Numpy_Scipy - Fatal编程技术网

Python 延长线路以与另一条线路平滑连接

Python 延长线路以与另一条线路平滑连接,python,numpy,scipy,Python,Numpy,Scipy,我有两条像这样的曲线: 我正在寻找一种将蓝色曲线与红色曲线平滑连接的方法,方法是将前者(蓝色线)向上延伸到右侧,而将后者(红色线)保持不变。方向很重要,我之所以提到这一点,是因为看起来将蓝线延续到左边会更容易。我不能这样做(在我的大代码中没有意义),所以它必须向上和向右 以下是我迄今为止所做的工作(两条线接近的部分放大): 基本上,我使用两条曲线(黑点)的点样本来插值一条新曲线,MWEcode获取此图的代码如下 我现在需要做的是找到一种方法,将绿线从它与红线相交的点修剪到它与蓝线相交的点,并

我有两条像这样的曲线:

我正在寻找一种将蓝色曲线与红色曲线平滑连接的方法,方法是将前者(蓝色线)向上延伸到右侧,而将后者(红色线)保持不变。方向很重要,我之所以提到这一点,是因为看起来将蓝线延续到左边会更容易。我不能这样做(在我的大代码中没有意义),所以它必须向上和向右

以下是我迄今为止所做的工作(两条线接近的部分放大):

基本上,我使用两条曲线(黑点)的点样本来插值一条新曲线,
MWE
code获取此图的代码如下

我现在需要做的是找到一种方法,将绿线从它与红线相交的点修剪到它与蓝线相交的点,并延伸蓝线,替换现在不再需要的最后一小段

这是应用(手动)上述更改后蓝线的外观:

其中,绿线的修剪部分现在是蓝线的一部分。请注意,我有:

  • 放弃延伸到与红线相交处以外的绿线的额外点
  • 放弃绿线中超出与蓝线交点的额外点
  • 在丢弃蓝线中超出绿线和蓝线交叉点的部分后,将绿线的剩余部分附加到蓝线
  • 因为我已经有了插值曲线(绿线),所以我只需要一种方法:

  • 修剪到与其他两条曲线相交的点,如上所述
  • 用新插值线的修剪部分替换蓝线的最后一部分
  • 在这个特定的例子中,我使用了固定列表来绘制和执行计算,但是我有几对线,我需要对它们执行类似的操作,因此解决方案必须足够通用,以考虑具有相似形状但不同曲线的情况。我怎么能这样做

    我欢迎使用
    numpy
    scipy
    或任何必要的解决方案

    以下是
    MWE

    import numpy as np
    import matplotlib.pyplot as plt
    
    # Red line data.
    x1 = [0.01, 0.04, 0.08, 0.11, 0.15, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.38, 0.41, 0.44, 0.46, 0.49, 0.51, 0.54, 0.56, 0.58]
    y1 = [2.04, 2.14, 2.24, 2.34, 2.44, 2.54, 2.64, 2.74, 2.84, 2.94, 3.04, 3.14, 3.24, 3.34, 3.44, 3.54, 3.64, 3.74, 3.84, 3.94]
    
    # Blue line data.
    x2 = [0.4634, 0.4497, 0.4375, 0.4268, 0.4175, 0.4095, 0.4027, 0.3971, 0.3925, 0.389, 0.3865, 0.3848, 0.384, 0.3839, 0.3845, 0.3857, 0.3874, 0.3896, 0.3922, 0.3951, 0.3982, 0.4016, 0.405, 0.4085, 0.412, 0.4154, 0.4186, 0.4215, 0.4242, 0.4265, 0.4283, 0.4297, 0.4304, 0.4305, 0.4298, 0.4284, 0.4261, 0.4228, 0.4185, 0.4132, 0.4067, 0.399, 0.39, 0.3796, 0.3679, 0.3546, 0.3397, 0.3232, 0.305, 0.285]
    y2 = [1.0252, 1.0593, 1.0934, 1.1275, 1.1616, 1.1957, 1.2298, 1.2639, 1.298, 1.3321, 1.3662, 1.4003, 1.4344, 1.4685, 1.5026, 1.5367, 1.5708, 1.6049, 1.639, 1.6731, 1.7072, 1.7413, 1.7754, 1.8095, 1.8436, 1.8776, 1.9117, 1.9458, 1.9799, 2.014, 2.0481, 2.0822, 2.1163, 2.1504, 2.1845, 2.2186, 2.2527, 2.2868, 2.3209, 2.355, 2.3891, 2.4232, 2.4573, 2.4914, 2.5255, 2.5596, 2.5937, 2.6278, 2.6619, 2.696]
    
    x3, y3 = [], []
    
    # Store a small section of the blue line in these new lists: only those points
    # closer than 0.2 to the last point in this line.
    for indx,y2_i in enumerate(y2):
        if (y2[-1]-y2_i)<=0.2:
            y3.append(y2_i)
            x3.append(x2[indx])
    
    # The same as above but for the red line: store only those points between
    # 0. and 0.4 in the y axis and with a larger x value than the last point in the
    # blue line.
    for indx,y1_i in enumerate(y1):
        if 0. <(y1_i-y2[-1])<=0.4 and x1[indx] > x2[-1]:
            y3.append(y1_i)
            x3.append(x1[indx])
    
    # Find interpolating curve that joins both segments stored in x3,y3.
    poli_order = 3 # Order of the polynome.
    poli = np.polyfit(y3, x3, poli_order)
    y_pol = np.linspace(min(y3), max(y3), 50)
    p = np.poly1d(poli)
    x_pol = [p(i) for i in y_pol]
    
    plt.plot(x1,y1, 'r')
    plt.plot(x2,y2, 'b')
    plt.plot(x_pol,y_pol, 'g')
    plt.scatter(x3,y3,c='k')
    
    plt.show()
    
    将numpy导入为np
    将matplotlib.pyplot作为plt导入
    #红线数据。
    x1=[0.01,0.04,0.08,0.11,0.15,0.18,0.22,0.25,0.29,0.32,0.35,0.38,0.41,0.44,0.46,0.49,0.51,0.54,0.56,0.58]
    y1=[2.04,2.14,2.24,2.34,2.44,2.54,2.64,2.74,2.84,2.94,3.04,3.14,3.24,3.34,3.44,3.54,3.64,3.74,3.84,3.94]
    #蓝线数据。
    x2=[0.4634, 0.4497, 0.4375, 0.4268, 0.4175, 0.4095, 0.4027, 0.3971, 0.3925, 0.389, 0.3865, 0.3848, 0.384, 0.3839, 0.3845, 0.3857, 0.3874, 0.3896, 0.3922, 0.3951, 0.3982, 0.4016, 0.405, 0.4085, 0.412, 0.4154, 0.4186, 0.4215, 0.4242, 0.4265, 0.4283, 0.4297, 0.4304, 0.4305, 0.4298, 0.4284, 0.4261, 0.4228, 0.4185, 0.4132, 0.4067, 0.399, 0.39, 0.3796, 0.3679, 0.3546, 0.3397, 0.3232, 0.305, 0.285]
    y2=[1.0252, 1.0593, 1.0934, 1.1275, 1.1616, 1.1957, 1.2298, 1.2639, 1.298, 1.3321, 1.3662, 1.4003, 1.4344, 1.4685, 1.5026, 1.5367, 1.5708, 1.6049, 1.639, 1.6731, 1.7072, 1.7413, 1.7754, 1.8095, 1.8436, 1.8776, 1.9117, 1.9458, 1.9799, 2.014, 2.0481, 2.0822, 2.1163, 2.1504, 2.1845, 2.2186, 2.2527, 2.2868, 2.3209, 2.355, 2.3891, 2.4232, 2.4573, 2.4914, 2.5255, 2.5596, 2.5937, 2.6278, 2.6619, 2.696]
    x3,y3=[],[]
    #在这些新列表中存储蓝线的一小部分:仅那些点
    #距离此线中最后一点的距离小于0.2。
    对于indx,枚举中的y2_i(y2):
    
    如果(y2[-1]-y2_i)您只能在一条线上使用两个点,在另一条线上使用两个点(只要它们位于交叉点的右侧),并在它们之间使用do a 4

    或者,一个更好的结果(有时)是使用曲线(现在你可以有4个以上的点,但代价是增加了复杂性)甚至是曲线。不幸的是,我已经有一段时间没有使用它们了,我不想为此编写一些代码


    拾取曲线时,请仔细查看其属性。例如,Bezier保证曲线不会离开由点确定的凸多边形,因此它显然是您需要的最佳候选曲线。

    如其他人所述,尝试使用样条曲线。从连续曲线开始,平滑曲线在导数中不太平滑直线到直线的s线看起来像f’(x)中的不连续。因此,我将边界从0.4收紧到0.2,这只抓住一个点来拟合红线。否则样条曲线将围绕额外的红色点过度插值

    下面是一个使用您的定义的快速示例:

    from scipy.interpolate import spline
    sx = np.array(x2+x3)
    sy = np.array(y2+y3)
    t  = np.arange(sx.size,dtype=float)
    t /= t[-1]
    N  = np.linspace(0,1,2000)
    SX = spline(t,sx,N,order=4)
    SY = spline(t,sy,N,order=4)
    
    plt.plot(x1,y1, 'r')
    plt.plot(x2,y2, 'b')
    plt.scatter(x3,y3,c='k')
    
    plt.plot(SX, SY,'g',alpha=.7,lw=3)    
    plt.show()
    

    这个问题是一个方便的参考:


    在一条线上只使用两点,在另一条线上只使用两点,然后进行样条插值或贝塞尔插值。是否将您的建议以答案的形式提出?:)我甚至对其进行了一些扩展,但我不想花时间为其编写代码(忙碌的一天,只有在编译代码时才来这里)正如你所说,我试图在将边界收紧到0.2的同时应用此代码,我得到了这样一个结果:你介意发布整个代码,看看我做错了什么吗?请划掉上面的注释。我刚刚意识到你删除了
    for
    块,在该块中,我将蓝色曲线中的点添加到
    x3,y3