我有一个 x
和 y
的值的列表,两个曲线都有奇怪的形状,并且我没有任何功能。我需要做两件事:
- 绘制它并像下图一样遮盖曲线之间的区域。
- 找到曲线之间该阴影区域的总面积。
我能够使用 fill_betweeen
和 fill_betweenx
matplotlib
绘制和阴影这些曲线之间的区域,但是我不知道如何计算计算它们之间的确切区域,特别是因为我没有任何这些曲线功能。
有什么想法吗?
我到处都看,找不到一个简单的解决方案。我非常绝望,因此,任何帮助都非常感谢。
非常感谢!

编辑:为将来的参考(如果任何人遇到相同的问题),这就是我如何解决此问题:将每个曲线的第一个和最后一个节点/点连接在一起,从而导致一个大怪异形状的多边形,然后使用 shapely 自动计算多边形的区域,这是曲线之间的确切区域他们是多么非线性。像魅力一样工作! :)
这是我的代码:
from shapely.geometry import Polygon
x_y_curve1 = [(0.121,0.232),(2.898,4.554),(7.865,9.987)] #these are your points for curve 1 (I just put some random numbers)
x_y_curve2 = [(1.221,1.232),(3.898,5.554),(8.865,7.987)] #these are your points for curve 2 (I just put some random numbers)
polygon_points = [] #creates a empty list where we will append the points to create the polygon
for xyvalue in x_y_curve1:
polygon_points.append([xyvalue[0],xyvalue[1]]) #append all xy points for curve 1
for xyvalue in x_y_curve2[::-1]:
polygon_points.append([xyvalue[0],xyvalue[1]]) #append all xy points for curve 2 in the reverse order (from last point to first point)
for xyvalue in x_y_curve1[0:1]:
polygon_points.append([xyvalue[0],xyvalue[1]]) #append the first point in curve 1 again, to it "closes" the polygon
polygon = Polygon(polygon_points)
area = polygon.area
print(area)
编辑2:感谢您的答案。就像凯尔(Kyle)所解释的那样,这仅适用于积极价值。如果您的曲线低于0(如示例图表中所示,这不是我的情况),那么您必须使用绝对数字。
I have a list of x
and y
values for two curves, both having weird shapes, and I don't have a function for any of them. I need to do two things:
- Plot it and shade the area between the curves like the image below.
- Find the total area of this shaded region between the curves.
I'm able to plot and shade the area between those curves with fill_between
and fill_betweenx
in matplotlib
, but I have no idea on how to calculate the exact area between them, specially because I don't have a function for any of those curves.
Any ideas?
I looked everywhere and can't find a simple solution for this. I'm quite desperate, so any help is much appreciated.
Thank you very much!

EDIT: For future reference (in case anyone runs into the same problem), here is how I've solved this: connected the first and last node/point of each curve together, resulting in a big weird-shaped polygon, then used shapely to calculate the polygon's area automatically, which is the exact area between the curves, no matter which way they go or how nonlinear they are. Works like a charm! :)
Here is my code:
from shapely.geometry import Polygon
x_y_curve1 = [(0.121,0.232),(2.898,4.554),(7.865,9.987)] #these are your points for curve 1 (I just put some random numbers)
x_y_curve2 = [(1.221,1.232),(3.898,5.554),(8.865,7.987)] #these are your points for curve 2 (I just put some random numbers)
polygon_points = [] #creates a empty list where we will append the points to create the polygon
for xyvalue in x_y_curve1:
polygon_points.append([xyvalue[0],xyvalue[1]]) #append all xy points for curve 1
for xyvalue in x_y_curve2[::-1]:
polygon_points.append([xyvalue[0],xyvalue[1]]) #append all xy points for curve 2 in the reverse order (from last point to first point)
for xyvalue in x_y_curve1[0:1]:
polygon_points.append([xyvalue[0],xyvalue[1]]) #append the first point in curve 1 again, to it "closes" the polygon
polygon = Polygon(polygon_points)
area = polygon.area
print(area)
EDIT 2: Thank you for the answers. Like Kyle explained, this only works for positive values. If your curves go below 0 (which is not my case, as showed in the example chart), then you would have to work with absolute numbers.
发布评论
评论(8)
该区域计算在两条曲线没有相交的块中很简单:那是上面指出的梯形。如果它们相交,则在x [i]和x [i+1]之间创建两个三角形,并且应该添加两者的区域。如果您想直接执行此操作,则应分别处理两种情况。这是解决您的问题的基本工作示例。首先,我将从一些虚假数据开始:
现在,主要代码。根据您的情节,看起来您在同一x点上定义了Y1和Y2。然后,我们定义,
每当两个图形交叉时,cross_test都是负。在这些点,我们要计算交叉的X坐标。为简单起见,我将计算Y段的交点的X坐标。对于两条曲线不相交的地方,它们将是无用的值,我们不会在任何地方使用它们。这只是使代码更容易理解。
假设您在x1和x2处有z1和z2,然后我们要求解x0,以便z = 0:
曲线不相交的地方,区域简单地给出:
它们相交的地方,我们添加两个三角形的区域:
现在,现在,现在,要选择每个块x [i]至x [i+1]中的区域,我在其中使用np.:
这是您所需的答案。正如上面指出的那样,如果两个y图在不同的x点上定义,这将变得更加复杂。如果您想测试它,可以简单地绘制它(在我的测试案例中,Y范围为-20至20)
The area calculation is straightforward in blocks where the two curves don't intersect: thats the trapezium as has been pointed out above. If they intersect, then you create two triangles between x[i] and x[i+1], and you should add the area of the two. If you want to do it directly, you should handle the two cases separately. Here's a basic working example to solve your problem. First, I will start with some fake data:
Now, the main code. Based on your plot, looks like you have y1 and y2 defined at the same X points. Then we define,
cross_test will be negative whenever the two graphs cross. At these points, we want to calculate the x coordinate of the crossover. For simplicity, I will calculate x coordinates of the intersection of all segments of y. For places where the two curves don't intersect, they will be useless values, and we won't use them anywhere. This just keeps the code easier to understand.
Suppose you have z1 and z2 at x1 and x2, then we are solving for x0 such that z = 0:
Where the curves don't intersect, area is simply given by:
Where they intersect, we add areas of both triangles:
Now, the area in each block x[i] to x[i+1] is to be selected, for which I use np.where:
That is your desired answer. As has been pointed out above, this will get more complicated if the both the y graphs were defined at different x points. If you want to test this, you can simply plot it (in my test case, y range will be -20 to 20)
将两条曲线定义为函数
f
和g
,它们是按段线性的,例如x1
和x2
之间代码> f(x)= f(x1) +((x-x1)/(x2-x1))*(f(x2)-f(x1))。定义
h(x)= abs(g(x)-f(x))
。然后使用scipy.integrate.quad
集成h。这样,您就不需要打扰交叉点了。它将自动执行CH41RMN建议的“空中求和”。
Define your two curves as functions
f
andg
that are linear by segment, e.g. betweenx1
andx2
,f(x) = f(x1) + ((x-x1)/(x2-x1))*(f(x2)-f(x1))
.Define
h(x)=abs(g(x)-f(x))
. Then usescipy.integrate.quad
to integrate h.That way you don't need to bother about the intersections. It will do the "trapeze summing" suggested by ch41rmn automatically.
从某种意义上说,这两组数据共享相同的X坐标物,您的数据集非常“不错”。因此,您可以使用一系列梯形来计算该区域。
例如,将两个函数定义为f(x)和g(x),然后,在x中的任何两个连续点之间,您有四个数据点:
然后,梯形的面积是
一个并发症,即方程(1)仅出现。为简单连接的区域作品,即在该区域内不得有交叉:
交叉路口的两个侧面必须分别评估。您需要浏览数据以查找所有交叉点,然后将其坐标插入您的坐标列表中。必须保持X的正确顺序。然后,您可以循环浏览简单连接区域的列表,并获得梯形区域的总和。
编辑:
出于好奇的缘故,如果两个列表的X坐标是不同的,则可以构建三角形。例如,
必须避免在三角形之间重叠,因此您将需要再次找到交叉点并将其插入订购列表中。可以使用毕达哥拉斯的公式来计算三角形的每一侧的长度,并且可以使用苍鹭的公式计算三角形的面积。
Your set of data is quite "nice" in the sense that the two sets of data share the same set of x-coordinates. You can therefore calculate the area using a series of trapezoids.
e.g. define the two functions as f(x) and g(x), then, between any two consecutive points in x, you have four points of data:
Then, the area of the trapezoid is
A complication arises that equation (1) only works for simply-connected regions, i.e. there must not be a cross-over within this region:
The area of the two sides of the intersection must be evaluated separately. You will need to go through your data to find all points of intersections, then insert their coordinates into your list of coordinates. The correct order of x must be maintained. Then, you can loop through your list of simply connected regions and obtain a sum of the area of trapezoids.
EDIT:
For curiosity's sake, if the x-coordinates for the two lists are different, you can instead construct triangles. e.g.
Overlap between triangles must be avoided, so you will again need to find points of intersections and insert them into your ordered list. The lengths of each side of the triangle can be calculated using Pythagoras' formula, and the area of the triangles can be calculated using Heron's formula.
我遇到了同样的问题。下面的答案是基于问题作者的尝试。但是,Shapely不会直接以紫色给出多边形的面积。您需要编辑代码以将其分解为其组件多边形,然后获取每个组件的区域。之后 - 您只是将它们添加。
两行之间的区域
考虑下面的行:
样品两行
如果您在下面运行代码,则会将面积零零,因为它沿顺时针旋转并减去抗顺时针区域:
因此,解决方案是根据线相交的位置将多边形分成较小的片段。然后使用for循环添加这些:
I had the same problem.The answer below is based on an attempt by the question author. However, shapely will not directly give the area of the polygon in purple. You need to edit the code to break it up into its component polygons and then get the area of each. After-which you simply add them up.
Area Between two lines
Consider the lines below:
Sample Two lines
If you run the code below you will get zero for area because it takes the clockwise and subtracts the anti clockwise area:
The solution is therefore to split the polygon into smaller pieces based on where the lines intersect. Then use a for loop to add these up:
PYPI库中的
aint_between_two_curves
函数The
area_between_two_curves
function in pypi library similaritymeasures (released in 2018) might give you what you need. I tried a trivial example on my side, comparing the area between a function and a constant value and got pretty close tie-back to Excel (within 2%). Not sure why it doesn't give me 100% tie-back, maybe I am doing something wrong. Worth considering though.一般多边形区域的直接应用(参见 shoelace公式)简单而快速,矢量化计算:
在两条曲线之间的区域应用。在此示例中,我们甚至没有匹配的X坐标!
图:
速度
两种曲线具有100万点的
:多边形区域计算的简单效果
A straightforward application of the area of a general polygon (see Shoelace formula) makes for a super-simple and fast, vectorized calculation:
Application to area between two curves. In this example, we don't even have matching x coordinates!
Plot:
Speed
For both curves having 1 million points:
Simple viz of polygon area calculation
该线程上的任何答案都没有完成我想要的,因此我将一些不同的资源合并在一起。我明确希望获得两个相交功能的正区域,其中许多方法在取消区域时存在问题。在此示例中,我正在计算犯罪曲线和y = 0之间的区域,该区域为4个。
要点: https://gist.github.com/amstrudy/0bddab089c7ee36ab49aec8d2363648d
None of the answers on this thread did what I wanted, so I merged a few different sources together. I was explicitly looking to get the positive area of two intersecting functions, and a lot of these approaches had issues with areas cancelling out. In this example, I am calculating the area between a sin curve and y = 0, which for one full period is 4.
Gist here: https://gist.github.com/amstrudy/0bddab089c7ee36ab49aec8d2363648d
一种优雅的方法是将函数和 shapely.demetry 软件包。
fill_betthe()
返回a 对象,您可以从中获得每个多边形的路径。好事是您甚至可以分别计算y2> y1
和y2< y1
的区域。An elegant way to do that is by combining the fill_between() function and the Polygon function in the
shapely.geometry
package.fill_between()
returns a PolyCollection object, from which you can get the paths of each polygon. The good thing is you can even compute the area separately fory2>y1
andy2<y1
.