3

I want to display the PlotPoints and MaxRecursion values used to plot the current graph so that the user can change the values relatively to improve the output. Is it possible to get the PlotPoints and MaxRecursion information from a plot?

a = 
  Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 Pi}, 
    PlotPoints -> 10, MaxRecursion -> 2]

PlotRange[a]
PlotPoints[a]
MaxRecursion[a]
m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Prashanth
  • 325
  • 1
  • 11
  • 1
    Options[a,PlotRange]. – yulinlinyu Apr 25 '16 at 02:09
  • AbsoluteOptions can help a little.You can get the value of PlotRange like this AbsoluteOptions[a, PlotRange]But the value of PlotPoints and MaxRecursion Maybe be vanished after you get the a. – yode Apr 25 '16 at 02:16
  • 1
    If the goal is to expose these values to users, you might try to pass them to the PlotLabel too. Or you could pass them to a combined Text graphic as shown in the 3rd example on howTo/MakeASmootherOrRougherPlot. This shows a dynamic example with labels for MaxRecursion and PlotPoints. – Rashid Apr 25 '16 at 03:24
  • my requirement is, to first plot the graph using Automatic. And if the user is not satisfied with the result, he could change the options. For the user to easily change the option values, I thought it would be good to show them the current values. – Prashanth Apr 25 '16 at 04:06
  • If you are trying to make an interactive application where the user can control certain plot parameter, you should simply take control by explicitly giving values for those parameters that user will permitted to change. – m_goldberg Apr 25 '16 at 04:11
  • @m_goldberg Yes that is one way to do it. However using Automatic at first will produce better plots than any fixed number. Is there someway to calculate PlotPoints based on the number of points seen in FullForm[a] ? – Prashanth Apr 25 '16 at 04:15
  • 2
    As far I know there is no way to get the values used for MaxRecursion or PlotPoints from the result of evaluating a Plot expression. – m_goldberg Apr 25 '16 at 04:56

1 Answers1

7

You can do something like this,

SetAttributes[verbosePlot, HoldAll]
verbosePlot[plotcommand_] := Module[{plot, pp, mr},
  {pp, mr} = {PlotPoints, 
     MaxRecursion} /. (Trace[plot = plotcommand, 
         HoldPattern[(MaxRecursion -> _Integer) | (PlotPoints -> _Integer)],
         TraceInternal -> True] // Flatten // Reverse // 
      ReleaseHold);
  Print@*Row /@ {{"MaxRecursions \[Rule] ", 
     mr}, {"PlotPoints \[Rule] ", pp}, {"PlotRange \[Rule] ", 
     Charting`get2DPlotRange@plotcommand}};
  plot
  ]

Here we are using Trace to find the actual values of MaxRecursion and PlotPoints used, and the undocumented function Charting`get2DPlotRange@plotcommand to get the PlotRange (a different method is needed for this option since Trace will return PlotRange->All if that is the option given).

Thanks to Simon Woods for this method, and thanks to J.M. for the tips on improving it. This will plot the command and give the values for the requested option.

verbosePlot[Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 Pi}]]

enter image description here

another example,

verbosePlot[
 ParametricPlot[
  r^2 { Sqrt[t] Cos[t], Sin[t]}, {t, 0, 3 Pi/2}, {r, 1, 2}]]

enter image description here

If you want to extract the option values from an already created plot, I don't know how to do that. The only information available in the FullForm of the plot would be the number of mesh points, not the algorithm used to generate them.

Note that you can also bypass this user-defined function and go straight to TracePrint,

TracePrint[
 ParametricPlot[
  r^2 {Sqrt[t] Cos[t], Sin[t]}, {t, 0, 3 Pi/2}, {r, 1, 
   2}], (MaxRecursion -> _Integer) | (PlotPoints -> _Integer), 
 TraceInternal -> True]
Charting`get2DPlotRange@%

enter image description here

if you don't mind the duplicated results from TracePrint

Jason B.
  • 68,381
  • 3
  • 139
  • 286
  • I would like to know how did you know the usage of the functions that located in context Charting. Thanks:) – xyz Apr 25 '16 at 08:55
  • I got Charting`get2DPlotRange and Charting`get3DPlotRange from hanging around here, very useful functions. I don't know what else is in the Charting` package though – Jason B. Apr 25 '16 at 08:57
  • @ShutaoTANG - but there do seem to be a lot of them: Names["Charting`*"] – Jason B. Apr 25 '16 at 08:58
  • In general, I using ?Charting` :) A few days ago, I saw this function in your answer – xyz Apr 25 '16 at 09:05
  • Ahhh, but these are undocumented functions, so you won't find any documentation that way :-D – Jason B. Apr 25 '16 at 09:07
  • Yes, they are undocumented, so I think these functions are designed for the WRI developers, rather than the general users. – xyz Apr 25 '16 at 09:10
  • For your perusal: TracePrint[Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 π}], (MaxRecursion -> _Integer) | (PlotPoints -> _Integer), TraceInternal -> True]. You can then apply Charting`get2DPlotRange[] to the output afterwards. (N.B. PlotRange[graphics] and Charting`get2DPlotRange[graphics] will have different results in general, depending on the PlotRangePadding setting.) – J. M.'s missing motivation Apr 25 '16 at 09:17
  • @J.M. , any idea why PlotPoints /. Flatten@Trace[ plot = Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 \[Pi]}], (MaxRecursion -> _Integer) | (PlotPoints -> _Integer), TraceInternal -> True] doesn't work? It claims that "..... is not a list of replacement rules", but Head /@{PlotPoints -> 50, PlotPoints -> 50, MaxRecursion -> 6, MaxRecursion -> 6} returns {Rule, Rule, Rule, Rule} – Jason B. Apr 25 '16 at 09:23
  • Did you have a look at the FullForm[] of the output of Flatten[(* stuff *)]? – J. M.'s missing motivation Apr 25 '16 at 09:25
  • @J.M. also I went for the charting option since if you give PlotRange->All, then Trace doesn't seem to give any numeric values. – Jason B. Apr 25 '16 at 09:29
  • Yes, I was merely anticipating people who might ask why you didn't just extract PlotRange from the resulting Graphics[] object. – J. M.'s missing motivation Apr 25 '16 at 09:31
  • Nice (+1). PlotRange works as a function for both 2D and 3D plots. – kglr Apr 25 '16 at 11:32
  • @kglr, that's what I told Jason; the only snag in that is that it doesn't account for PlotRangePadding. – J. M.'s missing motivation Apr 25 '16 at 13:42
  • @kglr Thanks, I missed that, I wanted to make it versatile but the Charting functions only work for 2D or 3D. I will check later, but is it the case that PlotRange will return the exact range given if you state it explicitly. But also give a numeric range if you use Automatic or Full? – Jason B. Apr 25 '16 at 18:22
  • @JasonB thanks for the answer. But the TracePrint is not working for RegionPlot[reg] cases. For example, RegionPlot[ImplicitRegion[x > 10 && y < 10, {x, y}]] – Prashanth Apr 26 '16 at 02:37