\begingroup
我知道有很多关于这个问题的帖子,但我就是找不到解决我的问题的正确帖子。问题是我有两个数据集,我使用它们来绘制它们ListLinePlot
。我想用不同的颜色填充它们包围的区域(当 A 位于 B 上时使用绿色,当 B 位于 A 上时使用黄色)。但这个简单的问题却很有挑战性。无论我如何使用命令,它对Filling
区域使用的颜色始终相同(见照片)。我知道一种方法是找到交点然后重新生成数据,但我不想弄乱它。我相信应该有一个简单的解决方法。
其次,如何分别计算这两个面积?
以下是代码:
test1 = {{0.01, 21.96}, {0.19, 22.06}, {0.36, 22.06}, {0.54,
22.06}, {0.71, 22.06}, {0.89, 22.06}, {1.06, 22.05}, {1.24,
22.05}, {1.41, 22.06}, {1.59, 22.05}, {1.76, 22.05}, {1.94,
22.05}, {2.11, 22.05}, {2.29, 22.05}, {2.46, 22.06}, {2.64,
22.04}, {2.81, 22.03}, {2.99, 21.96}, {3.16, 21.79}, {3.34,
20.56}, {3.51, 16.5}, {3.69, 11.71}, {3.86, 7.62}, {4.04,
4.52}, {4.21, 3.19}, {4.39, 2.99}, {4.56, 2.95}, {4.74,
2.95}, {4.91, 2.95}, {5.09, 2.95}, {5.26, 2.96}, {5.44,
2.96}, {5.61, 2.96}, {5.79, 2.96}, {5.96, 2.96}, {6.14, 2.96}};
test2 = {{0.02, 22.16}, {0.08, 22.14}, {0.16, 22.07}, {0.22,
22.07}, {0.29, 22.07}, {0.36, 22.07}, {0.44, 22.06}, {0.5,
22.06}, {0.58, 22.06}, {0.64, 22.06}, {0.72, 22.06}, {0.78,
22.06}, {0.86, 22.06}, {0.92, 22.06}, {1., 22.06}, {1.06,
22.06}, {1.14, 22.06}, {1.2, 22.06}, {1.27, 22.06}, {1.34,
22.06}, {1.41, 22.06}, {1.48, 22.06}, {1.56, 22.06}, {1.62,
22.06}, {1.69, 22.06}, {1.76, 22.06}, {1.84, 22.06}, {1.9, 22.06},
{1.97, 22.06}, {2.04, 22.06}, {2.11, 22.06}, {2.18, 22.06}, {2.25,
22.06}, {2.32, 22.06}, {2.4, 22.06}, {2.46, 22.06}, {2.54,
22.06}, {2.6, 22.06}, {2.68, 22.06}, {2.74, 22.05}, {2.82,
22.05}, {2.88, 22.04}, {2.96, 22.02}, {3.02, 22.}, {3.09,
21.97}, {3.16, 21.92}, {3.24, 21.83}, {3.3, 21.73}, {3.38,
21.59}, {3.44, 21.34}, {3.52, 20.82}, {3.58, 17.72}, {3.66,
12.82}, {3.72, 9.42}, {3.8, 6.91}, {3.86, 5.12}, {3.94,
4.05}, {4., 3.51}, {4.08, 3.25}, {4.14, 3.13}, {4.22,
3.06}, {4.28, 3.02}, {4.36, 3.}, {4.42, 2.99}, {4.5, 2.99}, {4.57,
2.99}, {4.63, 2.99}, {4.7, 2.99}, {4.78, 2.99}, {4.84,
2.99}, {4.92, 2.99}, {4.98, 2.99}, {5.05, 2.99}, {5.12,
2.99}, {5.2, 2.99}, {5.26, 2.99}, {5.34, 2.99}, {5.4,
2.99}, {5.48, 2.99}, {5.54, 2.99}, {5.62, 2.99}, {5.68,
2.99}, {5.76, 2.99}, {5.82, 2.99}, {5.9, 2.99}, {5.96,
2.99}, {6.04, 2.99}, {6.1, 2.99}, {6.18, 2.99}, {6.24, 2.99}};
ListLinePlot[{test1, test2}, Filling -> {1 -> {{2}, {Yellow, Green}}}]
谢谢
\endgroup
2
最佳答案
3
\begingroup
看起来这些点需要位于相同的 x 值。
我首先创建线性插值并选择两个插值的域内的 x 值:
int1 = Interpolation[test1, InterpolationOrder -> 1];
int2 = Interpolation[test2, InterpolationOrder -> 1];
xPoints = Union[test1[[All, 1]], test2[[All, 1]]];
(*select points that are in the range of both interpolations*)
domains = Interval[#["Domain"][[1]]] & /@ {int1, int2};
range = IntervalIntersection @@ domains;
xPoints = Select[xPoints, IntervalMemberQ[range, #] &];
然后评估这些点的插值:
p1 = {#, int1[#]} & /@ xPoints;
p2 = {#, int2[#]} & /@ xPoints;
ListLinePlot[{p1, p2}, Filling -> {1 -> {{2}, {Yellow, Green}}}]
然后使用Clip
我定义两个仅当int2 > int1
或int1 > int2
时才为非零的函数。我绘制了这些截断函数的绝对值来显示这种行为:
(*define diff to be the difference between the interpolations*)
diff[x_] = int1[x] - int2[x];
(*when int2>int1,diff is negative*)
yellowReg[x_] := Clip[diff[x], {-Infinity, 0}]
(*when int1>int2,diff is positive*)
greenReg[x_] := Clip[diff[x], {0, Infinity}];
Plot[{Abs@yellowReg[x], Abs@greenReg[x]}, {x, xPoints[[1]],
xPoints[[-1]]}, Filling -> Axis, PlotStyle -> {Yellow, Green},
FillingStyle -> Opacity[1], PlotRange -> All]
现在我们可以找到这两个区域的大小:
(*calculate magnitude of yellow and green regions*)
yellowArea =
NIntegrate[yellowReg[x], {x, xPoints[[1]], xPoints[[-1]]}] // Abs
greenArea =
NIntegrate[greenReg[x], {x, xPoints[[1]], xPoints[[-1]]}] // Abs
(*1.12331*)
(*0.814679*)
请注意,黄色区域还包括左侧的小区域int2 > int1
。如果您不想包括该区域,可以将下积分边界更改xPoints[[1]]
为更大的区域,但仍然包括大黄色区域。
\endgroup
1
-
\begingroup
我喜欢你的回答。它提供的信息比我预期的要多。
\endgroup
–
|
\begingroup
- 两条线相交多次,不完全只有一个交点。我们可以通过以下方式看到这一点:
polys = PolygonDecomposition[Polygon[Join[Reverse@test1, test2]]];
n = Length[polys]
colors = {Yellow, Blue, Green, Brown, Red, Blue, Cyan};
mapping = Association[Thread[colors -> polys]]
Graphics[Thread[{colors, polys}], AspectRatio -> 1]
- 所以你想要红色和绿色多边形的面积。
{Area[mapping@Red], Area[mapping@Green]}
{1.03459, 0.814679}
\endgroup
1
-
\begingroup
完美答案!谢谢
\endgroup
–
|
\begingroup
由于你一开始没有给出任何数据,所以我随意制作了一些数据:
dat1 = Table[{x, -ArcTan[10 x]}, {x, -21, 21}] // N;
dat2 = Table[{x, -ArcTan[2 x]}, {x, -20, 20}] // N;
dat2 = Join[{dat1[[1]]}, dat2, {dat1[[-1]]}]
现在我们可以绘制这些数据了。以下是选项“填充”的格式,它将执行您想要的操作:
ListLinePlot[{dat1, dat2}, Filling -> {1 -> {{2}, {Blue, Red}}}]
要获得曲线之间两部分的面积,首先要通过点定义一个插值函数,然后进行积分:
f1 = Interpolation[dat1];
f2 = Interpolation[dat2];
NIntegrate[f1[x] - f2[x], {x, -21, 0}]
1.42858
-NIntegrate[f1[x] - f2[x], {x, 0, 21}]
1.42858
\endgroup
2
-
\begingroup
谢谢你的回答。我的命令中已经有了这个填充选项,但是没有用。
\endgroup
– -
\begingroup
我认为它不起作用的原因是 x 参数不一样。如果这是真的,您可以在“Plot”命令中使用插值函数,而不是使用“ListLinePlot”
\endgroup
–
|
这些
Filling
命令似乎有用,我想我输入的和你输入的完全一样?抱歉,我真的不知道如何确定是什么导致了Filling
这里的行为\endgroup
–
@ydd 请查看已编辑的帖子。
\endgroup
–
|