如何同步到 matplotlib 上的曲线?

How to synchronize to curves on matplotlib?

我有两条曲线,它们的最大值大致同时出现,但我想让它们完全匹配。 第一个函数 maxind 确定最大值在我的临时列表中的位置。 第二个函数,synchro(我需要帮助的地方),应该同步它们。

import numpy as np
import matplotlib.pyplot as plt


def generate_examples(shift=+1.0):
    # Generate two curves with different maximum
    xa = np.linspace(start=0, stop=6, num=1000)
    xb = np.linspace(start=0, stop=6, num=2000)

    ya = np.sin(xa)
    yb = np.sin(xb+shift)**3
    return (xa, ya), (xb, yb)


def maxind(T, L):
    n = len(L)
    M = - np.inf
    ind = 0
    for i in range(n):
        if L[i] > M:
            ind = i
            M = L[i]
    return ind, M, T[ind]


def synchro(xs, ys, TC, XT):
    indth, maxth, tth = maxind(xs, ys)
    indexp, maxexp, texp = maxind(TC, XT)
    L = []
    Tsync = []
    if indexp < indth:
        I = indth - indexp
        for i in range(I):
            xs.pop(0)
            ys.pop(0)
    else:
        I = indexp - indth
        for i in range(I, len(XT)):
            L.append(XT[i])
            Tsync.append(TC[i])

    return Tsync, L


(xa, ya), (xb, yb) = generate_examples(shift=+1.0)
Tsync, L = synchro(ys=xa, xs=ya, XT=xb, TC=yb)
fig, ax = plt.subplots()
ax.plot(xa, ya, color='blue', label='a')
ax.plot(xb, yb, color='red', ls=':', label='b')
ax.plot(L, Tsync, color='red', label='synced')

ax.legend()

我想把红色曲线的最大值和蓝色曲线的最大值放在同一时间点。

我试图根据您提供的代码构建一个工作示例。

我的解决方案使用 numpy,因为这使一些事情变得更容易,例如,您可以直接使用 argmax 函数而不是编写自己的 maxind 函数。查看代码中的注释以了解计算曲线 b 的索引偏移背后的逻辑。

import numpy as np
import matplotlib.pyplot as plt


def generate_examples(shift=+1.0):
    # Generate two curves with different maximum
    xa = np.linspace(start=0, stop=6, num=1000)
    xb = np.linspace(start=0, stop=6, num=2000)
    # note that this is a general case where the two curves have different x values,
    # if we assume that they are the same some calculations would become simpler

    ya = np.sin(xa)
    yb = np.sin(xb+shift)**3  # shift maximum by defined value
    return (xa, ya), (xb, yb)


def calculate_shift(xa, ya, xb, yb):
    # Get (first) maximum for a and b
    iya = np.argmax(ya)
    iyb = np.argmax(yb)

    # Get the shift in terms of x
    dx = xb[iyb] - xa[iya]
    print('Shift', dx)  # should be roughly +/-1, as we build the examples this way

    # Find the shift in xb | find the index of xb which is closest to the shift in x
    xb0 = xb - xb[0]  # shift xb to ensure it starts with 0
    dxb = np.abs(dx) - xb0
    ixb = np.argmin(np.abs(dxb))

    # returned the signed shift in indices of xb
    return int(ixb * np.sign(dx))


def plot(xa, ya, xb, yb,
         ixb):
    fig, ax = plt.subplots()
    ax.plot(xa, ya, color='blue', label='a')
    ax.plot(xb, yb, color='red', ls=':', label='b')
    if ixb > 0:
        ax.plot(xb[:-ixb], yb[ixb:], color='red', label='b - shifted')
    else:
        ax.plot(xb[-ixb:], yb[:ixb], color='red', label='b - shifted')

    ax.legend()


(xa, ya), (xb, yb) = generate_examples(shift=-1.0)
ixb = calculate_shift(xa, ya, xb, yb)
plot(xa, ya, xb, yb, ixb)