2

I have a fairly complicated scalar analytical function of 3 variables that appears to be quite incompatible with SliceContourPlot3D (I shut it down after a few minutes without results). What is the correct way to visualize it in 3D space using not 3D data array as suggested by ListSliceContourPlot3D, but rather precalculated data on 2D planes which I'm trying to visualize? In other words, I'm trying to do ListContourPlot in few different planes and arrange results in 3D space accordingly.

Also there is another problem when ListContourPlot3D gives empty box: A dump file with NNSolution array that creates empty ListSliceContourPlot3D[NNSolution, "CenterPlanes"].

Example:

Structured tables look alright:

data = Table[Sqrt[x^2 + y^2 + z^2], {z, 0, 3, 0.1}, {y, 0, 3, 0.1}, {x, 0, 3, 0.1}];
ListSliceContourPlot3D[data, "CentralPlanes"]

enter image description here

But unstructured data is pretty bad:

data1 = Flatten[
          Table[
            {x, y, z, Sqrt[x^2 + y^2 + z^2]}, 
            {z, 0, 3, 0.1}, {y, 0, 3, 0.1}, {x, 0, 3, 0.1}
          ],
        1];
ListSliceContourPlot3D[data1, "CentralPlanes"]

enter image description here

In two-dimensional case they are indistinguishable:

data1 = Flatten[Table[{z, y, Sqrt[y^2 + z^2]}, {z, 0, 3, 0.1}, {y, 0, 3, 0.1}], 1];
ListContourPlot[data1]

enter image description here

data = Table[Sqrt[y^2 + z^2], {z, 0, 3, 0.1}, {y, 0, 3, 0.1}];
ListContourPlot[data]

enter image description here

This is a rationale for using 2D contours and aligning them in 3D instead of 3D slice plot.

This is my silly version:

data1 = Flatten[Table[{x, y, Sqrt[(y + 1/2)^2 + (x - 1/2)^2]}, {x, -2, 2, 0.1}, {y, -2, 2, 0.1}], 1];
data2 = Flatten[Table[{y, z, Sqrt[(0 - 1/2)^2 + (y + 1/2)^2 + z^2]}, {y, -2, 2, 0.1}, {z, -2, 2, 0.1}], 1];
data3 = Flatten[Table[{x, z, Sqrt[(x - 1/2)^2 + (0 - 1/2)^2 + z^2]}, {x, -2, 2, 0.1}, {z, -2, 2, 0.1}], 1];
aa1 = Image[
ListContourPlot[data1, Frame -> False, ColorFunctionScaling -> False, Contours -> {0.15, 0.5, 1, 1.5, 2, 2.5}], ImageSize -> 200];
aa2 = Image[ListContourPlot[data2, Frame -> False, ColorFunctionScaling -> False, Contours -> {0.15, 0.5, 1, 1.5, 2, 2.5}], ImageSize -> 200];
aa3 = Image[ListContourPlot[data3, Frame -> False, ColorFunctionScaling -> False, Contours -> {0.15, 0.5, 1, 1.5, 2, 2.5}], ImageSize -> 200];
ParametricPlot3D[{{x, y, 0}, {0, x, y}, {x, 0, y}}, {x, -1, 1}, {y, -1, 1}, 
PlotStyle -> {Texture[aa1], Texture[aa2], Texture[aa3]}, Mesh -> False]

enter image description here

Note that textures look blurry and the whole thing is quite slow.

kglr
  • 394,356
  • 18
  • 477
  • 896
Vsevolod A.
  • 959
  • 5
  • 15

1 Answers1

3

The data in your example is actually structured. If you change the level specification in Flatten to 2 the result is the same as the one you get using your data:

data2 = Flatten[Table[{x, y, z, Sqrt[x^2 + y^2 + z^2]}, {z, -2, 2, .1}, 
  {y, -2,  2, .1}, {x, -2, 2, .1}],  2]; 
ListSliceContourPlot3D[data2, "CenterPlanes"]

enter image description here

Update: An alternative way to use 2D ContourPlots as center planes:

ClearAll[postprocess]
postprocess = MapIndexed[(# /. Graphics[ GraphicsComplex[c_, prims___], ___] :> 
  Graphics3D[GraphicsComplex[Function[{t}, Insert[t, 0, #2[[1]]]] /@ c, 
   {Opacity[0.8], prims}]]) &, #]&;

data0 = Flatten[Table[{x, y, z, Sqrt[x^2 + y^2 + z^2]}, {z, -2, 2, .1}, 
  {y, -2, 2, .1}, {x, -2, 2, .1}], 2];
data2D = data0[[All, {## & @@ #, 4}]] & /@ Subsets[Range[3], {2}];
lcp2D = ListContourPlot[#, Contours -> 10, PlotRange -> All, 
     ColorFunction -> "Rainbow", ContourStyle -> Thick] & /@ data2D;
Show[postprocess @ lcp2D, PlotRange -> All]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
  • Your implementation is much better, thank you. However there's something wrong - if I change x to x-1 in function from data0, it tears, like one of the planes is not showing what it should. – Vsevolod A. May 31 '18 at 16:18