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

时间:2011-03-19 18:44:59

标签: wolfram-mathematica

使用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]}]]

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

任何建议都将不胜感激。

7 个答案:

答案 0 :(得分:16)

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

提取积分的一种方法如下:

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

ListPlot'看一看'

ListPlot[points]

给出以下内容:

enter image description here

修改 布雷特冠军指出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

Yaroslav Bulatov也应该交叉引用并承认this非常好的答案。

编辑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。

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

就ListPlot而言,OP问题可以如下获得:

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

编辑4

更简单

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

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

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

评估为True

plot[[1, 1, 3, 2, 1]] == Cases[plot, Line[{x__}] -> x, Infinity]

答案 1 :(得分:14)

一种方法是将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>>}}

答案 2 :(得分:9)

除了Leonid's answer中提到的方法和我的后续评论之外,要实时跟踪慢功能的绘图进度以查看发生的情况,您可以执行以下操作(使用{{3}的示例最近的问题):

(* 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

答案 3 :(得分:6)

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

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

答案 4 :(得分:4)

根据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

答案 5 :(得分:3)

另一种方式,可能依赖于实现:

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

enter image description here

答案 6 :(得分:3)

只需看一下情节的结构(对于不同类型的情节,会有一些不同的结构)并使用类似的东西:

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