了解 Mathematica 轮廓线提取
Understanding Mathematica contour lines extraction
我的教授寄给我一个 Mathematica 笔记本,他在其中绘制了一个二维轮廓,然后将轮廓提取为线(即坐标元组列表的列表)。具体的代码段是这样的:
xdiv = 0.05
zt = 1.
lis = Table[SomeFunction[x, y, zt], {y, -xmax, xmax, xdiv}, {x, -xmax, xmax, xdiv}];
plot = ListContourPlot[lis, PlotLegends -> Automatic, Contours -> {0}, ContourShading -> None];
lines = Cases[Normal@plot, Line[pts_, ___] :> xdiv*pts, Infinity];
我不完全理解代码究竟是如何做的,我正在寻求帮助以获得解释。我想在 python 中编写类似的代码并了解如何操作。我还想知道是否可以在不使用 ContourPlot 函数的情况下提取线条。我对绘制轮廓不是特别感兴趣,我只需要它的线条列表。
编辑:改写了问题。
另外:matplotlib - extracting data from contour lines 似乎解释了如何在 python 中实现我的目标。但是,我真的不明白如何 它做了它所做的事情,并判断是否有更好的方法,在性能方面,来实现它(我正在处理非常大的列表,所以这个轮廓提取似乎是瓶颈)。我一直在寻找更多的解释来理解究竟发生了什么。提供的答案在解释 Mathematica 代码方面确实做得很好。我将阅读更多有关 matplotlib 方法的内容。
下面是对正在发生的事情的一些解释,以及一个示例函数:
SomeFunction[x_, y_, zt_] := Sin[3 x + y^2]
xmax = 4;
xdiv = 0.05;
zt = 1.;
lis = Table[SomeFunction[x, y, zt], {y, -xmax, xmax, xdiv}, {x, -xmax, xmax, xdiv}];
plot = ListContourPlot[lis, PlotLegends -> Automatic, Contours -> {0},
ContourShading -> None];
normalplot = Normal@plot
cases = Cases[normalplot, Line[pts_, ___], Infinity];
Length[cases]
First[cases]
17
Line[{{16.2216, 1.}, {17., 1.29614}, ... , {16.7818, 160.782}, {16.2216, 161.}}]
Cases
语句从归一化图中提取每一行。 (Normal
将图形形式简化为 Cases
。)Line[List[{x, y}, {x, y}, ...]]
.
形式有 17 行单独的行
对于每一行 List[{x, y}, {x, y}, ...]
由 pts
表示,所以
lines = Cases[normalplot, Line[pts_, ___] :> xdiv*pts, Infinity]
将 pts
的每个列表乘以 xdiv
。
0.05 * {{16.2216, 1.}, {17., 1.29614}, ... , {16.7818, 160.782}, {16.2216, 161.}}
= {{0.81108, 0.05}, {0.85, 0.0648069}, ... {0.839088, 8.03909}, {0.81108, 8.05}}
可以绘制线条。
ListLinePlot[lines, AspectRatio -> 1]
我的教授寄给我一个 Mathematica 笔记本,他在其中绘制了一个二维轮廓,然后将轮廓提取为线(即坐标元组列表的列表)。具体的代码段是这样的:
xdiv = 0.05
zt = 1.
lis = Table[SomeFunction[x, y, zt], {y, -xmax, xmax, xdiv}, {x, -xmax, xmax, xdiv}];
plot = ListContourPlot[lis, PlotLegends -> Automatic, Contours -> {0}, ContourShading -> None];
lines = Cases[Normal@plot, Line[pts_, ___] :> xdiv*pts, Infinity];
我不完全理解代码究竟是如何做的,我正在寻求帮助以获得解释。我想在 python 中编写类似的代码并了解如何操作。我还想知道是否可以在不使用 ContourPlot 函数的情况下提取线条。我对绘制轮廓不是特别感兴趣,我只需要它的线条列表。
编辑:改写了问题。 另外:matplotlib - extracting data from contour lines 似乎解释了如何在 python 中实现我的目标。但是,我真的不明白如何 它做了它所做的事情,并判断是否有更好的方法,在性能方面,来实现它(我正在处理非常大的列表,所以这个轮廓提取似乎是瓶颈)。我一直在寻找更多的解释来理解究竟发生了什么。提供的答案在解释 Mathematica 代码方面确实做得很好。我将阅读更多有关 matplotlib 方法的内容。
下面是对正在发生的事情的一些解释,以及一个示例函数:
SomeFunction[x_, y_, zt_] := Sin[3 x + y^2]
xmax = 4;
xdiv = 0.05;
zt = 1.;
lis = Table[SomeFunction[x, y, zt], {y, -xmax, xmax, xdiv}, {x, -xmax, xmax, xdiv}];
plot = ListContourPlot[lis, PlotLegends -> Automatic, Contours -> {0},
ContourShading -> None];
normalplot = Normal@plot
cases = Cases[normalplot, Line[pts_, ___], Infinity];
Length[cases]
First[cases]
17 Line[{{16.2216, 1.}, {17., 1.29614}, ... , {16.7818, 160.782}, {16.2216, 161.}}]
Cases
语句从归一化图中提取每一行。 (Normal
将图形形式简化为 Cases
。)Line[List[{x, y}, {x, y}, ...]]
.
对于每一行 List[{x, y}, {x, y}, ...]
由 pts
表示,所以
lines = Cases[normalplot, Line[pts_, ___] :> xdiv*pts, Infinity]
将 pts
的每个列表乘以 xdiv
。
0.05 * {{16.2216, 1.}, {17., 1.29614}, ... , {16.7818, 160.782}, {16.2216, 161.}}
= {{0.81108, 0.05}, {0.85, 0.0648069}, ... {0.839088, 8.03909}, {0.81108, 8.05}}
可以绘制线条。
ListLinePlot[lines, AspectRatio -> 1]