【问题标题】:Plotting the sum of multiple plot lines绘制多条绘图线的总和
【发布时间】:2020-03-06 18:23:37
【问题描述】:

我使用数组中的数据绘制了多条线。问题是我想绘制一条新线来显示所有这些线的总和。请记住,每组的 x 值是不同的。 让我举一个我正在尝试做的例子。假设我有 2 组 (x,y) 数据,如下所示:

 x1=np.array([1,2,3,4,5])
 y1=np.array([1,3,5,7,9])
 x2=np.array([3,4,5,6,7])
 y2=np.array([2,4,6,8,10])

然后,我使用 np.interp

 xvals1=np.linspace(1,5,1000)
 yinterp1 = np.interp(xvals1, x1, y1)
 plt.plot(xvals1, yinterp1)
 xvals2=np.linspace(3,7,1000)
 yinterp2 = np.interp(xvals2, x2, y2)
 plt.plot(xvals2, yinterp2)

好的,所以现在,我想要一个额外的行来显示这两行的总和。但如果我执行以下操作,它会给我一条绝对错误的线(绿色):

xvals=np.linspace(1,7,1000)
plt.plot(xvals,yinterp1+yinterp2)

有人对此有任何想法吗?

【问题讨论】:

  • 怎么了? y 数据无法知道哪个 x 有意义。您正在绘制一个 x, y 集,两者的点数相同,因此不会引发错误。唯一有效的数据是yinterp1[1 <= xvals1 & xvals1 <= 5]yinterp2[3 <= xvals2 & xvals2 <= 7]
  • 当您执行y1+ y2 时,结果为[y1[0]+y2[0], y1[1]+y2[1], ...]。在您的特定情况下,索引对应于不同的值,因此您实际上是在执行[y1[x=1]+y2[x=3], ..., y1[x=5]+y2[x=7]],这没有物理意义。
  • 是的,我明白你在说什么。我所说的只是我试图做的,因为我没有任何其他想法,我知道这是错误的,这就是我发布这个问题的原因,以找到正确的方法
  • 哦,那没问题,这只是屏蔽数据的问题!请看我的回答:)

标签: python arrays numpy matplotlib plot


【解决方案1】:

当您执行y1+ y2 时,结果为[y1[0]+y2[0], y1[1]+y2[1], ...]。在您的特定情况下,索引对应于不同的值,因此您实际上是在执行[y1[x=1]+y2[x=3], ..., y1[x=5]+y2[x=7]],这没有物理意义。

我们需要屏蔽这些值,以便它们有意义,并且 y 被“对齐”以进行添加。对齐的意思是同一个索引对应同一个x

import numpy as np
import matplotlib.pyplot as plt

x1 = np.array([1, 2, 3, 4, 5])
y1 = np.array([1, 3, 5, 7, 9])
x2 = np.array([3, 4, 5, 6, 7])
y2 = np.array([2, 4, 6, 8, 10])

xvals1 = np.linspace(1, 5, 1000)
yinterp1 = np.interp(xvals1, x1, y1)
plt.plot(xvals1, yinterp1)

xvals2 = np.linspace(3, 7, 1000)
yinterp2 = np.interp(xvals2, x2, y2)
plt.plot(xvals2, yinterp2)

xvals = np.linspace(1, 7, 1000)
x1_and_x2_intersection_mask = (np.logical_and(3 <= xvals, xvals <= 5))
xinter = xvals[x1_and_x2_intersection_mask]
yi1 = yinterp1[x1_and_x2_intersection_mask]
yi2 = yinterp2[x1_and_x2_intersection_mask]
plt.plot(xinter, yi1+yi2)

现在关于您的评论,删除上面代码的最后一行并添加:

def mask_between_a_b(array, a, b):
    """I make functions when I have to use something more than once."""
    return np.logical_and(a <= array, array <= b)

# Create the masked data for the two regions where blue and orange don't share an x.
x1_mask = mask_between_a_b(x1, 1, 3)
x2_mask = mask_between_a_b(x2, 5, 7)

x1m = x1[x1_mask]
y1m = y1[x1_mask]
x2m = x2[x2_mask]
y2m = y2[x2_mask]

# Add all three regions together to get the full curve.
x = list(x1m) + list(xinter) + list(x2m)
y = list(y1m) + list(yi1+yi2) + list(y2m)
plt.plot(x, y)

你只需要小心掩蔽,我猜边界可以自动创建,但这超出了问题的范围。

【讨论】:

  • 感谢您的回答。这几乎是我想要的。有没有什么办法让绿线覆盖整个区域?(所以对于 1
  • @PhilF。是的,只要您执行操作的区域有意义,就可以使用任意数量的数据集进行操作。这里我们手动进行了屏蔽,但最好的解决方案是创建一个函数 f(x1, y1, x2, y2) 专用于返回 x1[mask], y1[mask], x2[mask], y2[mask]mask 沿着 (x1 in x2 ∩ x2 in x1) 的行。
  • 非常感谢您的完整回答。我试过你说的,它有效!不幸的是,有很多交叉掩码,因为我有很多 (x,y) 集,经过一些尝试,我仍然没有得到所有这些的正确“总和”行,但我会尝试更多。再次感谢
【解决方案2】:

您不能添加y 值,因为对应的x 值不同。要添加它们,您将需要相同范围内的 x 值。例如,在您的代码中,添加的第一个点将是 f1(1) + f2(3) 的结果,这不是您想要的。你要的是f1(1) + f2(1)

你应该这样做

 xvals1=np.linspace(1,5,5)
 yinterp1 = np.interp(xvals1, x1, y1)
 plt.plot(xvals1, yinterp1)
 xvals2=np.linspace(1,5,5)
 yinterp2 = np.interp(xvals2, x2, y2)
 plt.plot(xvals2, yinterp2)
 xvals=np.linspace(1,5,5)
 plt.plot(xvals,yinterp1+yinterp2)

此外,您还必须将y2 的值从1 定义为7,因为您需要从17 的求和行。

【讨论】:

    猜你喜欢
    • 2019-10-27
    • 2018-10-02
    • 2017-06-13
    • 2021-09-15
    • 2018-03-30
    • 2014-07-27
    • 1970-01-01
    • 2014-06-14
    • 2017-10-05
    相关资源
    最近更新 更多