Reconstructing ContourPlot with ListContourPlot - Mathematica Stack Exchange most recent 30 from mathematica.stackexchange.com 2019-08-19T09:09:25Z https://mathematica.stackexchange.com/feeds/question/151938 http://www.creativecommons.org/licenses/by-sa/3.0/rdf https://mathematica.stackexchange.com/q/151938 9 Reconstructing ContourPlot with ListContourPlot JEM_Mosig https://mathematica.stackexchange.com/users/35390 2017-07-20T21:45:54Z 2018-10-15T18:00:47Z <p>Let <code>f</code> be some numeric function with two arguments</p> <pre><code>f[x_?NumericQ, y_?NumericQ] := x y </code></pre> <p>For the purposes of this question <code>f</code> has a very simple form, but the function I am actually working with takes several seconds to evaluate. Therefore, I want to store every evaluation of <code>f</code>. This could be done with a memory function (<code>memf[x_,y_]:=memf[x,y]=f[x,y]</code>), but here I use <code>Sow</code> instead, i.e.</p> <pre><code>sowf[x_?NumericQ, y_?NumericQ] := (Sow[{x, y, f[x, y]}, "f"]; f[x, y]) </code></pre> <p>Now create a <code>ContourPlot</code> of <code>sowf</code> with</p> <pre><code>{plot, {{fPts}, {monitorPts}}} = Reap[ ContourPlot[ sowf[x, y], {x, 0, 1}, {y, 0, 1}, EvaluationMonitor :&gt; Sow[{x, y, f[x, y]}, "monitor"], PlotTheme -&gt; "Monochrome", PlotPoints -&gt; 3, MaxRecursion -&gt; 0 ], {"f", "monitor"} ]; </code></pre> <p>The plot is now stored in <code>plot</code>, while <code>fPts</code> contains all results of evaluations of <code>sowf</code> and <code>monitorPts</code> contains all points that where sent to <code>EvaluationMonitor</code>.</p> <p>Remark: I thought those two sets of points should be the same, but in fact <code>sowf</code> was evaluated one more time than <code>EvaluationMonitor</code> suggests:</p> <pre><code>Length /@ {fPts, monitorPts} (* {10, 9} *) Complement[fPts, monitorPts] (* {{0.0005, 0.0005, 2.5*10^-7}} *) </code></pre> <p>The computation above will be done with the expensive <code>f</code> on a computer cluster, and I want to make some adjustments to the plot style and other options later on, without having to re-evaluate <code>f</code>.</p> <p>My question is, how can I use either set of points to reconstruct the <code>ContourPlot</code>, using a <code>ListContourPlot</code>? Simply providing <code>ListContourPlot</code> with one of those sets results in a different plot:</p> <pre><code>contours = Sort@Cases[plot, Tooltip[__, n_] :&gt; n, \[Infinity]] (* {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9} *) Show[{ plot, ListContourPlot[monitorPts, ContourStyle -&gt; Directive[Thick, Cyan, Dashed], ColorFunction -&gt; (Transparent &amp;), Contours -&gt; contours] }] </code></pre> <p><a href="https://i.stack.imgur.com/uou5v.png" rel="noreferrer"><img src="https://i.stack.imgur.com/uou5v.png" alt="enter image description here"></a></p> <pre><code>Show[{ plot, ListContourPlot[fPts, ContourStyle -&gt; Directive[Thick, Cyan, Dashed], ColorFunction -&gt; (Transparent &amp;), Contours -&gt; contours] }] </code></pre> <p><a href="https://i.stack.imgur.com/0Za62.png" rel="noreferrer"><img src="https://i.stack.imgur.com/0Za62.png" alt="enter image description here"></a></p> <p>Note, that <code>ListContourPlot</code> does not show all the contours I specified! The contours for 0.9, 0.8, and 0.7 are missing.</p> <pre><code>Tally@Cases[%, Tooltip[__, n_] :&gt; n, \[Infinity]] (* {{0.9, 1}, {0.8, 1}, {0.7, 1}, {0.6, 2}, {0.5, 2}, {0.4, 2}, {0.3, 2}, {0.2, 2}, {0.1, 2}} *) </code></pre> <p>What additional information does <code>ContourPlot</code> use?</p> <p>When the number of points is large enough it works fine</p> <pre><code>{plot, {{fPts}, {monitorPts}}} = Reap[ ContourPlot[ sowf[x, y], {x, 0, 1}, {y, 0, 1}, EvaluationMonitor :&gt; Sow[{x, y, f[x, y]}, "monitor"], PlotTheme -&gt; "Monochrome" ], {"f", "monitor"} ]; Show[{ plot, ListContourPlot[fPts, ContourStyle -&gt; Directive[Thick, Cyan, Dashed], ColorFunction -&gt; (Transparent &amp;)] }] </code></pre> <p><a href="https://i.stack.imgur.com/JaTWB.png" rel="noreferrer"><img src="https://i.stack.imgur.com/JaTWB.png" alt="enter image description here"></a></p> <p>but the actual <code>f</code> is, as I mentioned before, very expensive to evaluate, so I want to keep the number of plot points relatively low.</p> https://mathematica.stackexchange.com/questions/151938/-/151939#151939 1 Answer by JEM_Mosig for Reconstructing ContourPlot with ListContourPlot JEM_Mosig https://mathematica.stackexchange.com/users/35390 2017-07-20T21:45:54Z 2017-07-20T21:45:54Z <p>[Partial Answer - Please add your own answers as well!]</p> <p>I cannot really explain why <code>ListContourPlot</code> and <code>ContourPlot</code> give different results, but there is a workaround using only <code>ContourPlot</code>.</p> <p>We can create the plot as before</p> <pre><code>{plot, {fPts}} = Reap[ ContourPlot[ sowf[x, y], {x, 0, 1}, {y, 0, 1}, PlotTheme -&gt; "Monochrome", PlotPoints -&gt; 3, MaxRecursion -&gt; 0 ] ]; </code></pre> <p>and then define a memory-function</p> <pre><code>ClearAll[memf]; Do[memf[p[], p[]] = p[], {p, fPts}]; </code></pre> <p>to be used by <code>ContourPlot</code> with exactly the same settings for <code>PlotPoints</code> and <code>MaxRecursion</code> as before.</p> <p>This requires, however, some amount of faith in Wolfram not changing anything in the <code>ContourPlot</code> routine from one MMA version to the next.</p> https://mathematica.stackexchange.com/questions/151938/-/181944#181944 0 Answer by bbgodfrey for Reconstructing ContourPlot with ListContourPlot bbgodfrey https://mathematica.stackexchange.com/users/1063 2018-09-15T17:17:48Z 2018-09-15T17:17:48Z <p>Probably, <code>ContourPlot</code> and <code>ListContourPlot</code> use different <code>Method</code>s for the same set of function points. See, for instance, the first answer to <a href="https://i.stack.imgur.com/t07KZ.png" rel="nofollow noreferrer">question 69448</a>. Not having the patience to experiment with these many possibilities, I suggest building an <code>Interpolation</code> function from <code>monitorPts</code>, and plot it with <code>ContourPlot</code>.</p> <pre><code>int = Interpolation[intpts = {Most@#, Last@#} &amp; /@ monitorPts, InterpolationOrder -&gt; 2]; Show[{plot, ContourPlot[int[x, y], {x, 0, 1}, {y, 0, 1}, PlotPoints -&gt; 3, MaxRecursion -&gt; 0, ContourStyle -&gt; Directive[Thick, Cyan, Dashed], ColorFunction -&gt; (Transparent &amp;), Contours -&gt; contours], ImageSize -&gt; Large}] </code></pre> <p><a href="https://i.stack.imgur.com/t07KZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/t07KZ.png" alt="enter image description here"></a></p> <p><code>InterpolationOrder -&gt; 2</code> can be omitted for larger values of <code>PlotPoints</code>.</p>