7
$\begingroup$

While plotting a slow to evaluate function and trying to get some sense of progress, I noticed that Mathematica traverses the grid of points twice. Here's the reduced example:

points = {};
Dynamic[
 Show[
   ListPlot[Take[points, Max[0, Length@points - 5]], PlotRange -> All],
   ListPlot[
     Take[points, -Min[Length@points, 5]], PlotRange -> All, 
     PlotStyle -> Directive[PointSize[Large], Opacity[0.1], Red]
   ],
   AspectRatio -> Automatic
 ]
]

Monitor[
  Plot3D[Pause[0.05]; 0, {a, -5, 5}, {b, -5, 5}, 
     PlotRange -> All, PlotPoints -> 10, MaxRecursion -> 0], 
 AppendTo[points, {a, b}];
]

If you watch the plot, you'll see that the red points move twice over the grid. If you inspect the plots variable after plotting, you'll see that not all the points are duplicates: some are offset from their originals by $\sim10^{-8}$.

Why does Plot3D do this, even though I asked for MaxRecursion -> 0? Is there any way to convince it to only scan the function once (not having to resort to ListPlot3D + Table)?

$\endgroup$
5
  • $\begingroup$ I am not sure why Plot3D does this, but you can avoid repeated evaluation using a memory pattern, e.g. f[x_, y_] := f[x, y] = .... $\endgroup$
    – JEM_Mosig
    Commented Jan 13, 2018 at 22:35
  • 3
    $\begingroup$ Maybe for computing the vertex normals? Try NormalsFunction -> None as option. $\endgroup$ Commented Jan 13, 2018 at 22:53
  • $\begingroup$ Ruslan, very nice animation, btw. $\endgroup$ Commented Jan 14, 2018 at 0:31
  • $\begingroup$ @HenrikSchumacher this appears to be correct. Why not post it as an answer? $\endgroup$
    – Ruslan
    Commented Jan 14, 2018 at 7:58
  • $\begingroup$ 1) The normals require 3 function evaluations (computed from finite differences), so that's a lot of overhead for a slow function. 2) You can add VertexNormals computed from the plot, instead of from the function, with Region`Mesh`MeshCellNormals. It helps to use Mesh -> All when converting the plot to a region: DiscretizeGraphics[Plot[..., Mesh -> All]]. $\endgroup$
    – Michael E2
    Commented Jan 14, 2018 at 14:46

1 Answer 1

6
$\begingroup$

I guess the second pass is for computing the vertex normals. At least the behavior of Plot3D is quite different (and somewhat erratic) when we set the option NormalsFunction -> None.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.