# ListContourPlot3D doesn't use all points

Edited thanks to @Kuba:

In the following example, ListContourPlot3D accepts an array of points spaced at intervals 0.1 apart throughout the volume, but seems to choose an arbitrary number of points for generating a mesh. Setting MaxPlotPoints explicitly works to a limited extent. How can I force it to use all points without specifying that number by hand?

gauss = Partition[
Flatten[Table[{i, j, k, Exp[-i^2 - j^2]}, {i, -2, 2, 0.1}, {j, -2,
2, 0.1}, {k, -2, 2, 0.1}]], 4];

GraphicsRow[{
ListContourPlot3D[gauss, Contours -> {0.5},
ContourStyle -> Opacity[0.5], AxesLabel -> {x, y, z}],
ListContourPlot3D[gauss, Contours -> {0.5},
ContourStyle -> Opacity[0.5], AxesLabel -> {x, y, z},
MaxPlotPoints -> 20],
ListContourPlot3D[gauss, Contours -> {0.5},
ContourStyle -> Opacity[0.5], AxesLabel -> {x, y, z},
MaxPlotPoints -> Infinity]
}, ImageSize -> 800]


Edit thanks to @Rahul:

For a 3D array (with the right order of indices) we get the right behavior. Does this mean the 4D syntax constructs the mesh in a fundamentally different way?

gauss = Table[Exp[-i^2 - j^2], {k, -2, 2, 0.1}, {j, -2, 2, 0.1}, {i, -2, 2, 0.1}];

ListContourPlot3D[gauss, Contours -> {0.5}, ContourStyle -> Opacity[0.5],
AxesLabel -> {x, y, z}, DataRange -> {{-2, 2}, {-2, 2}, {-2, 2}}]


Edit thanks to @Szabolcs:

Increasing MaxPlotPoints constructs the mesh with some strange regularities (and appears to slow it down):

GraphicsGrid[
Partition[
Table[ListContourPlot3D[gauss, Contours -> {0.5},
ContourStyle -> Opacity[0.5], AxesLabel -> {x, y, z},
MaxPlotPoints -> i, ImageSize -> 200,
PlotLabel ->
Style[StringJoin["MaxPlotPoints->", ToString[i]], 16, Bold]], {i,
18, 38, 4}], 3, 3, 1, Null], ImageSize -> 800]


-
@Nasser ListContourPlot3D dimensions are ok. –  Kuba Feb 21 '14 at 2:05
There is a fundamental difference, in the flat list case the interpolation scheme first has to sort out the connectivity somehow. Note you get the exact same result (just as fast) if you plot RandomSample[gauss, Length[gauss]] –  george2079 Feb 21 '14 at 15:45
I'm not sure what's going on, but experimenting with ListContourPlot (which is much faster so more convenient to play with), it seems that with MaxPlotPoints -> Infinity it does in fact include all points in the simple examples I tried (maybe not in more complicated ones). You can see this clearly if you use Mesh->All. However, if I use MaxPlotPoints -> 50or some other high value like that, then it included more points than I gave it. Probably it generates them using interpolation. You can even control it using InterpolationOrder. –  Szabolcs Feb 21 '14 at 16:02
To answer your question about the array vs 4-tuple syntax, yes, it does construct the mesh in a fundamentally different way. If you use the array version, it can take advantage of the regular structure of the grid and use any InterpolationOrder. If you give it values at arbitrary locations in 3D space, it will compute a Delaunay tessellation first and use that as the basis of the interpolation (which I think is limited to 1st or 0th order). So, I'm not sure what's going on, and I'm not saying that it does use all points in your example, but increasing MaxPlotPoints generates ... –  Szabolcs Feb 21 '14 at 16:10
... some extra points, not just necessarily include all existing ones. With a high value you'll be able to see the structure of the underlying grid and the cylinder will be jagged (pixelated-looking). It it possible that what ListContourPlot3D does is simply use Interpolation and invoke ContourPlot3D on the result? Just a guess. –  Szabolcs Feb 21 '14 at 16:11

Here is a work around, in case you need to work with the flat (unordered) data:

 interp = Interpolation[{#[[;; 3]], #[[4]]} & /@ gauss];
ContourPlot3D[interp[x, y, z], {x, -2, 2}, {y, -2, 2}, {z, -2, 2},Contours -> {.5}]


worth pointing out this seems to work fine for completely unordered data:

gauss = Table[
Join[#, {Exp[-#[[1]]^2 - #[[2]]^2 ]}] &@ RandomReal[{-2.1, 2.1}, 3], {8000}];
interp = Interpolation[{#[[;; 3]], #[[4]]} & /@ gauss];
ContourPlot3D[interp[x, y, z], {x, -2, 2}, {y, -2, 2}, {z, -2, 2}, Contours -> {.5}]


ListContoutPlot3D of the unordered data..

-
Great solution, thanks. For the random array, this method works, but I get Interpolation::udeg: Interpolation on unstructured grids is currently only supported for InterpolationOrder->1 or InterpolationOrder->All. Order will be reduced to 1. >> and the plot is much sloppier than yours. I assume it's because I'm running Mathematica 8. –  ninemileskid Feb 22 '14 at 4:14
@ninemileskid It is because you have specified InterpolationOrder other than 1: such interpolation is supported only on structured grids even in v.9. If you wish to use higher order interpolation, you should use third-party packages: Obtuse package, Non-Grid Interpolation Package. –  Alexey Popkov Feb 22 '14 at 8:30
Sorry - I get that warning with v9 as well. Since it worked I neglected to mention it. –  george2079 Feb 22 '14 at 12:42