The calculation of the area is simple in blocks where the two curves do not intersect: this is a trapezoid, as mentioned above. If they intersect, then you create two triangles between x [I] and x [g + 1], and you must add the area of two. If you want to do this directly, you must handle the two cases separately. Here is a basic working example to solve your problem. First, I'll start with some fake data:
#!/usr/bin/python import numpy as np # let us generate fake test data x = np.arange(10) y1 = np.random.rand(10) * 20 y2 = np.random.rand(10) * 20
Now, the main code. Based on your plot, it looks like you have y1 and y2 defined at the same points of X. Then we determine
z = y1-y2 dx = x[1:] - x[:-1] cross_test = np.sign(z[:-1] * z[1:])
cross_test will be negative whenever two charts intersect. At these points, we want to calculate the x coordinate of the crossover. For simplicity, I calculate the x coordinates of the intersection of all segments y. For places where the two curves do not intersect, they will be useless values, and we will not use them anywhere. It just makes code easier to understand.
Suppose that z1 and z2 at the point x1 and x2, then we solve for x0 that r = 0:
# (z2 - z1)/(x2 - x1) = (z0 - z1) / (x0 - x1) = -z1/(x0 - x1)
If the curves do not intersect, the area is simply set as follows:
areas_pos = abs(z[:-1] + z[1:]) * 0.5 * dx
When they intersect, we add areas of both triangles:
areas_neg = 0.5 * dx_intersect * abs(z[:-1]) + 0.5 * (dx - dx_intersect) * abs(z[1:])
Now, the area in each block x [I] x [g + 1] should be selected, for which I use np.where:
areas = np.where(cross_test < 0, areas_neg, areas_pos) total_area = np.sum(areas)
This is your desired answer. As mentioned above, this will become more complicated if both graphs y were defined at different x points. If you want to verify this, you can simply build it (in my test case, the y range will be from -20 to 20)
negatives = np.where(cross_test < 0) positives = np.where(cross_test >= 0) plot(x, y1) plot(x, y2) plot(x, z) plt.vlines(x_intersect[negatives], -20, 20)