如何同步到 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)
我有两条曲线,它们的最大值大致同时出现,但我想让它们完全匹配。
第一个函数 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)