Mathematica:如何获取plot命令绘制的数据点?

发布于 2024-10-24 08:41:12 字数 517 浏览 1 评论 0原文

当使用 Plot 绘制函数时,我想获取由 Plot 命令绘制的数据点集。

例如,如何获取以下简单示例中使用的点 {t,f} Plot 的列表?

f = Sin[t]
Plot[f, {t, 0, 10}]

我尝试使用一种将值附加到列表的方法,如 Jerry B. Keiper 的 Numerical1.ps(Mathematica 中的数值计算)的第 4 页所示,http://library.wolfram.com/infocenter/Conferences/4687/ 如下:

f = Sin[t]
flist={}
Plot[f, {t, 0, 10}, AppendTo[flist,{t,f[t]}]]

但无论我尝试什么,都会生成错误消息。

任何建议将不胜感激。

When plotting a function using Plot, I would like to obtain the set of data points plotted by the Plot command.

For instance, how can I obtain the list of points {t,f} Plot uses in the following simple example?

f = Sin[t]
Plot[f, {t, 0, 10}]

I tried using a method of appending values to a list, shown on page 4 of Numerical1.ps (Numerical Computation in Mathematica) by Jerry B. Keiper, http://library.wolfram.com/infocenter/Conferences/4687/ as follows:

f = Sin[t]
flist={}
Plot[f, {t, 0, 10}, AppendTo[flist,{t,f[t]}]]

but generate error messages no matter what I try.

Any suggestions would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

故事与诗 2024-10-31 08:41:13

除了 Leonid 中提到的方法回答和我的后续评论,要实时跟踪慢速函数的绘制进度以查看发生的情况,您可以执行以下操作(使用 这个最近的问题):

(* CPU intensive function *)
LogNormalStableCDF[{alpha_, beta_, gamma_, sigma_, delta_}, x_] :=
 Block[{u},
  NExpectation[
   CDF[StableDistribution[alpha, beta, gamma, sigma], (x - delta)/u], 
   u \[Distributed] LogNormalDistribution[Log[gamma], sigma]]]

(* real time tracking of plot process *)
res = {};
ListLinePlot[res // Sort, Mesh -> All] // Dynamic

Plot[(AppendTo[res, {x, #}]; #) &@
  LogNormalStableCDF[{1.5, 1, 1, 0.5, 1}, x], {x, -4, 6}, 
 PlotRange -> All, PlotPoints -> 10, MaxRecursion -> 4]

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

等。

In addition to the methods mentioned in Leonid's answer and my follow-up comment, to track plotting progress of slow functions in real time to see what's happening you could do the following (using the example of this recent question):

(* CPU intensive function *)
LogNormalStableCDF[{alpha_, beta_, gamma_, sigma_, delta_}, x_] :=
 Block[{u},
  NExpectation[
   CDF[StableDistribution[alpha, beta, gamma, sigma], (x - delta)/u], 
   u \[Distributed] LogNormalDistribution[Log[gamma], sigma]]]

(* real time tracking of plot process *)
res = {};
ListLinePlot[res // Sort, Mesh -> All] // Dynamic

Plot[(AppendTo[res, {x, #}]; #) &@
  LogNormalStableCDF[{1.5, 1, 1, 0.5, 1}, x], {x, -4, 6}, 
 PlotRange -> All, PlotPoints -> 10, MaxRecursion -> 4]

enter image description here

enter image description here

enter image description here

etc.

佼人 2024-10-31 08:41:13

这是获取所有数据点的非常有效的方法:

{plot, {points}} = Reap @ Plot[Last@Sow@{x, Sin[x]}, {x, 0, 4 Pi}]

Here is a very efficient way to get all the data points:

{plot, {points}} = Reap @ Plot[Last@Sow@{x, Sin[x]}, {x, 0, 4 Pi}]
世俗缘 2024-10-31 08:41:13

根据 Sjoerd C. de Vries 的回答,我现在编写了以下代码,该代码可自动执行绘图预览(在 Mathematica 8 上测试):

pairs[x_, y_List]:={x, #}& /@ y
pairs[x_, y_]:={x, y}
condtranspose[x:{{_List ..}..}]:=Transpose @ x
condtranspose[x_]:=x
Protect[SaveData]
MonitorPlot[f_, range_, options: OptionsPattern[]]:=
  Module[{data={}, plot},
    Module[{tmp=#},
      If[FilterRules[{options},SaveData]!={},
        ReleaseHold[Hold[SaveData=condtranspose[data]]/.FilterRules[{options},SaveData]];tmp]]&@
    Monitor[Plot[(data=Union[data, {pairs[range[[1]], #]}]; #)& @ f, range,
                 Evaluate[FilterRules[{options}, Options[Plot]]]],
      plot=ListLinePlot[condtranspose[data], Mesh->All,
      FilterRules[{options}, Options[ListLinePlot]]];
      Show[plot, Module[{yrange=Options[plot, PlotRange][[1,2,2]]},
        Graphics[Line[{{range[[1]], yrange[[1]]}, {range[[1]], yrange[[2]]}}]]]]]]
SetAttributes[MonitorPlot, HoldAll]

除了显示绘图的进度之外,它还标记了当前绘图的 x 位置计算。

主要问题是,对于多个绘图,Mathematica 对最终绘图中的所有曲线应用相同的绘图样式(有趣的是,它不在临时绘图上)。

要将生成的数据存入变量 dest,请使用选项 SaveData:>dest

Based on the answer of Sjoerd C. de Vries, I've now written the following code which automates a plot preview (tested on Mathematica 8):

pairs[x_, y_List]:={x, #}& /@ y
pairs[x_, y_]:={x, y}
condtranspose[x:{{_List ..}..}]:=Transpose @ x
condtranspose[x_]:=x
Protect[SaveData]
MonitorPlot[f_, range_, options: OptionsPattern[]]:=
  Module[{data={}, plot},
    Module[{tmp=#},
      If[FilterRules[{options},SaveData]!={},
        ReleaseHold[Hold[SaveData=condtranspose[data]]/.FilterRules[{options},SaveData]];tmp]]&@
    Monitor[Plot[(data=Union[data, {pairs[range[[1]], #]}]; #)& @ f, range,
                 Evaluate[FilterRules[{options}, Options[Plot]]]],
      plot=ListLinePlot[condtranspose[data], Mesh->All,
      FilterRules[{options}, Options[ListLinePlot]]];
      Show[plot, Module[{yrange=Options[plot, PlotRange][[1,2,2]]},
        Graphics[Line[{{range[[1]], yrange[[1]]}, {range[[1]], yrange[[2]]}}]]]]]]
SetAttributes[MonitorPlot, HoldAll]

In addition to showing the progress of the plot, it also marks the x position where it currently calculates.

The main problem is that for multiple plots, Mathematica applies the same plot style for all curves in the final plot (interestingly, it doesn't on the temporary plots).

To get the data produced into the variable dest, use the option SaveData:>dest

羁客 2024-10-31 08:41:13

另一种方式,可能取决于实现:

ListPlot@Flatten[
            Plot[Tan@t, {t, 0, 10}] /. Graphics[{{___, {_, y__}}}, ___] -> {y} /. Line -> List
         , 2]

在此处输入图像描述

Just another way, possibly implementation dependent:

ListPlot@Flatten[
            Plot[Tan@t, {t, 0, 10}] /. Graphics[{{___, {_, y__}}}, ___] -> {y} /. Line -> List
         , 2]

enter image description here

后知后觉 2024-10-31 08:41:13

只需查看绘图的结构(对于不同类型的绘图,结构会有一点不同)并使用类似的东西:

plt = Plot[Sin[x], {x, 0, 1}];
lstpoint = plt[[1, 1, 3, 2, 1]];

Just look into structure of plot (for different type of plots there would be a little bit different structure) and use something like that:

plt = Plot[Sin[x], {x, 0, 1}];
lstpoint = plt[[1, 1, 3, 2, 1]];
冰之心 2024-10-31 08:41:12
f = Sin[t];
plot = Plot[f, {t, 0, 10}]

提取点的一种方法如下:

points = Cases[
   Cases[InputForm[plot], Line[___], 
    Infinity], {_?NumericQ, _?NumericQ}, Infinity];

ListPlot“看一下”,

ListPlot[points]

给出以下内容:

在此处输入图像描述

编辑
Brett Champion 指出 InputForm 是多余的。

ListPlot@Cases[
  Cases[plot, Line[___], Infinity], {_?NumericQ, _?NumericQ}, 
  Infinity]

会起作用的。

也可以粘贴绘图图形,这有时很有用。比如说,如果我创建一个外部数据的 ListPlot,然后放错了数据文件(这样我只能访问生成的图形),我可以通过选择图形单元格括号、复制和粘贴来重新生成数据:

ListPlot@Transpose[{Range[10], 4 Range[10]}]

points = Cases[
  Cases[** Paste_Grphic _Here **, Point[___], 
   Infinity], {_?NumericQ, _?NumericQ}, Infinity] 

编辑2.

我还应该交叉引用并承认这一点雅罗斯拉夫·布拉托夫的回答非常好。

编辑 3

Brett Champion 不仅指出 FullForm 是多余的,而且在生成 GraphicsComplex 的情况下,应用 Normal 会将复数转换为基元。这非常有用。

例如:(

lp = ListPlot[Transpose[{Range[10], Range[10]}], 
  Filling -> Bottom]; Cases[
 Cases[Normal@lp, Point[___], 
  Infinity], {_?NumericQ, _?NumericQ}, Infinity] 

正确地)给出

{{1., 1.}, {2., 2.}, {3., 3.}, {4., 4.}, {5., 5.}, {6., 6. }, {7.,
7.}、{8.、8.}、{9.、9.}、{10.、10.}}

感谢 Brett Champion。

最后,使用这个答案中给出的一般方法的更简洁的方法,我发现这里

OP 问题,以 ListPlot 的形式,可以通过如下方式获得:

ListPlot@Cases[g, x_Line :> First@x, Infinity]

编辑 4

更简单的

ListPlot@Cases[plot, Line[{x__}] -> x, Infinity]

or

ListPlot@Cases[** Paste_Grphic _Here **, Line[{x__}] -> x, Infinity]

or

ListPlot@plot[[1, 1, 3, 2, 1]]

其计算结果为 True< /代码>

plot[[1, 1, 3, 2, 1]] == Cases[plot, Line[{x__}] -> x, Infinity]
f = Sin[t];
plot = Plot[f, {t, 0, 10}]

One way to extract points is as follows:

points = Cases[
   Cases[InputForm[plot], Line[___], 
    Infinity], {_?NumericQ, _?NumericQ}, Infinity];

ListPlot to 'take a look'

ListPlot[points]

giving the following:

enter image description here

EDIT
Brett Champion has pointed out that InputForm is superfluous.

ListPlot@Cases[
  Cases[plot, Line[___], Infinity], {_?NumericQ, _?NumericQ}, 
  Infinity]

will work.

It is also possible to paste in the plot graphic, and this is sometimes useful. If,say, I create a ListPlot of external data and then mislay the data file (so that I only have access to the generated graphic), I may regenerate the data by selecting the graphic cell bracket,copy and paste:

ListPlot@Transpose[{Range[10], 4 Range[10]}]

points = Cases[
  Cases[** Paste_Grphic _Here **, Point[___], 
   Infinity], {_?NumericQ, _?NumericQ}, Infinity] 

Edit 2.

I should also have cross-referenced and acknowledged this very nice answer by Yaroslav Bulatov.

Edit 3

Brett Champion has not only pointed out that FullForm is superfluous, but that in cases where a GraphicsComplex is generated, applying Normal will convert the complex into primitives. This can be very useful.

For example:

lp = ListPlot[Transpose[{Range[10], Range[10]}], 
  Filling -> Bottom]; Cases[
 Cases[Normal@lp, Point[___], 
  Infinity], {_?NumericQ, _?NumericQ}, Infinity] 

gives (correctly)

{{1., 1.}, {2., 2.}, {3., 3.}, {4., 4.}, {5., 5.}, {6., 6.}, {7.,
7.}, {8., 8.}, {9., 9.}, {10., 10.}}

Thanks to Brett Champion.

Finally, a neater way of using the general approach given in this answer, which I found here

The OP problem, in terms of a ListPlot, may be obtained as follows:

ListPlot@Cases[g, x_Line :> First@x, Infinity]

Edit 4

Even simpler

ListPlot@Cases[plot, Line[{x__}] -> x, Infinity]

or

ListPlot@Cases[** Paste_Grphic _Here **, Line[{x__}] -> x, Infinity]

or

ListPlot@plot[[1, 1, 3, 2, 1]]

This evaluates to True

plot[[1, 1, 3, 2, 1]] == Cases[plot, Line[{x__}] -> x, Infinity]
小鸟爱天空丶 2024-10-31 08:41:12

例如,一种方法是将 EvaluationMonitor 选项与 ReapSow 结合使用

In[4]:= 
(points = Reap[Plot[Sin[x],{x,0,4Pi},EvaluationMonitor:>Sow[{x,Sin[x]}]]][[2,1]])//Short

Out[4]//Short= {{2.56457*10^-7,2.56457*10^-7},<<699>>,{12.5621,-<<21>>}}

One way is to use EvaluationMonitor option with Reap and Sow, for example

In[4]:= 
(points = Reap[Plot[Sin[x],{x,0,4Pi},EvaluationMonitor:>Sow[{x,Sin[x]}]]][[2,1]])//Short

Out[4]//Short= {{2.56457*10^-7,2.56457*10^-7},<<699>>,{12.5621,-<<21>>}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文