【问题标题】:Finding the integral between two horizontally overlapping curves求两条水平重叠曲线之间的积分
【发布时间】:2021-09-21 17:58:23
【问题描述】:

我有一个从文本文件中绘制数据的代码。我已经能够得到每条数据曲线下的积分(虽然我不知道其中任何一个的函数,所以我只使用了integral = s = simps(y, x))。其中两条曲线水平重叠,我想找到它们重叠的区域。我遇到了一些麻烦,因为它们水平重叠而不是垂直重叠。我想找到的区域位于graph 的红线和蓝线之间。数据位于 numpy 数组中,例如,bxby 用于蓝线 x 和 y,rxry 用于红线 x 和 y。我没有代表它们的功能,但它们在那些数组中。很难知道如何进行,因为它们水平重叠而不是垂直重叠。

我很困惑,任何帮助将不胜感激!

更新:JohanC 提供的代码有worked in one casenot another。非工作图最初看起来像this(我只想要那个中间重叠区域的区域),但是当它也不起作用时,我尝试限制 x 范围以希望帮助代码缩小到我想计算重叠积分(这是那个范围较小的图的来源)。我目前使用的代码是JohanC 提供的代码,如下所示:

def get_overlap_integral(bx, by, rx, ry):
    fig, ax = plt.subplots()
    ax.plot(bx, by, color='b')
    ax.plot(rx, ry, color='r')

    # create a common x range
    gx = np.linspace(min(bx.min(), rx.min()), max(bx.max(), rx.max()), 1000)
    gby = np.interp(gx, bx, by)  # set bx,by onto the common x range
    gry = np.interp(gx, rx, ry)  # set rx,ry onto the common x range
    gy = np.minimum(gby, gry)  # let gx,gy be the intersection of the two curves
    ax.fill_between(gx, gy, color='g', alpha=0.3)

    area = np.trapz(gy, gx)  # calculate the green area
    ax.text(0.05, 0.95, f'Overlap: {area:.3f}', color='g', ha='left', va='top', transform=ax.transAxes)
    plt.show()
    return area

文本 bx、by、rx 和 ry 是这样的值:

BX: [999.5 999.  998.5 ... 201.  200.5 200. ]
BY: [-3.786867e-05 -4.366451e-05 -4.745308e-05 ...  1.068685e-05  1.555391e-05
 -8.949840e-06]
RX: [999.5 999.  998.5 ... 201.  200.5 200. ]
RY: [-5.865443e-05 -7.808241e-05 -5.887286e-05 ... -1.556630e-06 -3.473830e-06
 -6.367470e-06]

我不确定为什么此功能不适用于一种情况,但会完美地用于另一种情况。任何帮助将不胜感激!

【问题讨论】:

  • 你能创建一个可重现的例子吗?也许您可以添加数组的值(作为文本)?
  • 您的数组似乎顺序颠倒了,这给min(bx.min(), rx.min())np.interp 的逻辑带来了问题。您可以尝试在所有数组反转的情况下调用您的函数,例如get_overlap_integral(bx[::-1], by[::-1], rx[::-1], ry[::-1])

标签: python matplotlib plot integral simpsons-rule


【解决方案1】:

np.interp(new_x, old_x, old_y) 可以为新的 x 范围计算曲线。当设置在公共 x 范围上时,np.minimum 会找到两条正值曲线的公共区域。 np.trapz 计算面积。

这里是一些示例代码,从创建测试数据开始:

from matplotlib import pyplot as plt
import numpy as np

# create some test data
Nb = 300
bx = np.linspace(320, 750, Nb)
by = np.random.randn(Nb).cumsum()
by -= by[0]  # start at zero
by -= np.linspace(0, 1, Nb) * by[-1]  # let end in zero
by = (by ** 2) ** .3  # positive curve starting and ending with zero
Nr = 200
rx = np.linspace(610, 1080, Nr)
ry = np.random.randn(Nr).cumsum()
ry -= ry[0]  # start at zero
ry -= np.linspace(0, 1, Nr) * ry[-1]  # let end in zero
ry = (ry ** 2) ** .3  # positive curve starting and ending with zero

fig, ax = plt.subplots()
ax.plot(bx, by, color='b')
ax.plot(rx, ry, color='r')

# create a common x range
gx = np.linspace(min(bx.min(), rx.min()), max(bx.max(), rx.max()), 1000)
gby = np.interp(gx, bx, by)  # set bx,by onto the common x range
gry = np.interp(gx, rx, ry)  # set rx,ry onto the common x range
gy = np.minimum(gby, gry)  # let gx,gy be the intersection of the two curves
ax.fill_between(gx, gy, color='g', alpha=0.3)

area = np.trapz(gy, gx)  # calculate the green area
ax.text(0.05, 0.95, f'Overlap: {area:.3f}', color='g', ha='left', va='top', transform=ax.transAxes)
plt.show()

【讨论】:

  • 非常感谢您的帮助,其中一种情况已经奏效!在另一种情况下,它不是。我不确定为什么它在这种情况下不起作用,我查看了代码,但找不到出错的地方。你能提供一些见解吗?我将在我最初的问题中附上图片并在那里描述问题。
  • bx、by、rx 和 ry 是一维 numpy 数组吗?
  • 是的,它们是,例如其中一些中的前几个值:BX: [325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338....... e-03 1.09458069e-02 2.07035425e-02 3.46967871e-02 5.25319303e-02 7.35388438e-02 9.60352312e-02 ... ] RX:[ 610. 611. 612. 6.61. 6.61.7.7 614.7 618. 620. 621. ......] RY:[1.06681221CS-04 1.49827932E-04 2.17.050410932E-04 4.050410932E-04 1.759318092E-04 4.05041092E-04 1.759318092C-04 1.759318092C-04-04 1.7.05041092E-04 1.7.05041092E-04 1.7.05041092E-04-04 1.7.05041092E-04-04 1.7.050410532S-04-04 1.7.05041092E-04-04 1.7.05041092E-04-04 1.7.05041092E-04 1.7.05041092C-04- 03 5.11095889e-03 8.95907309e-03 ...]
猜你喜欢
  • 2019-08-15
  • 2020-06-16
  • 2017-10-12
  • 2016-11-19
  • 2014-12-28
  • 2013-02-27
相关资源
最近更新 更多