Labeling a three-dimensional plot

As the title says, I want to add some text in a three-dimensional plot, thus labeling specific parts of it. Here is the corresponding Mathematica code

V = 1/2*(x^2 + y^2 + z^2) + (x^2*y^2 + x^2*z^2 + y^2*z^2 - x^2*y^2*z^2);

E0 = 8.5;

S0 = ContourPlot3D[V == E0, {x, -5, 5}, {y, -5, 5}, {z, -5, 5},
PlotPoints -> 100, PerformanceGoal -> "Speed", Mesh -> None,
ContourStyle -> Directive[Green, Opacity[0.3], Specularity[White, 30]],
ImageSize -> 550, RegionFunction -> Function[{x, y, z},
Sqrt[x^2*y^2 + x^2*z^2 + y^2*z^2] <= 4]]


which gives this output

This surface contains eight symmetrical openings (holes) which I want to label using numbers 1, 2, ...., 8. Any suggestions how to do that? Would it be possible to "reduce" and project this surface into a two-dimensional plot in order to insert the labels? I suppose this would be interpreted more easily.

• @Kuba Just inserting text close to that holes. However, since you mentioned the location of the openings, I wouldn't say no to a way finding their coordinates! Sep 30, 2013 at 7:27

Let's assume that this expression doesn't have a simple form and that we can only work on the plot.

The only lines in the plot are those that come from the holes' boundaries, so we can extract them:

holes = Cases[S0 // Normal, Line[x__] :> x, Infinity];
pos = 1.2 (Mean /@ holes);
labels = Table[Inset[Style["Label " <> ToString[i], Bold, 20], pos[[i]]],
{i, Length@holes}];

Show[S0, Graphics3D[labels]]


Of course, you can calculate anatically what you need. It's just a different approach. Also, I've used Inset instead of Text so the labels can be covered by the plot and not always be in front.

Edit

in response to the comment:

order = Ordering @ {6, 8, 4, 2, 5, 7, 3, 1};
labels = Table[Inset[Style[order[[i]], Bold, 25], pos[[i]]], {i, Length@holes}];


• Very close to what I want! One minor drawback though, the numbering of the labels is automatic. How can I define my own sequence of numbers? In your case, 6,8,4,2,5,7,3,1 should be 1,2,3,4,5,6,7,8. Sep 30, 2013 at 7:49
• lost a little bit! could you incorporate the above patch to your original code? Sep 30, 2013 at 8:03
• @Vaggelis_Z done.
– Kuba
Sep 30, 2013 at 8:09
• I figured it out before your update! However, something is not right! 6,8,4,2,5,7,3,1 are now 1,5,8,2,4,6,3,7 instead of 1,2,3,4,5,6,7,8! Why? Sep 30, 2013 at 8:13
• @Vaggelis_Z I messed up with the order. It should be order = Ordering@{6, 8, 4, 2, 5, 7, 3, 1}
– Kuba
Sep 30, 2013 at 8:18

It seems that you want to add text to the 3D graphics. Therefore, using Epilog is not recommended, because it contains graphics primitives which are added after the 3D image is projected onto the 2D image plane. This is the reason why only two-dimensional primitives are possible in Epilog.

An easy solution to your problem is to create another 3D graphics containing your text and join both using Show

Show[S0, Graphics3D[Text[Framed@Style["MyLabel", Bold, 18], {2, -2, 2}]]]


Determination of the correct points

I kind of misread your question and thought you are you are only interested in a way to combine labels and 3D plot. Therefore, here an update on how you can determine the midpoints of your wholes.

Basically, it is exactly what you already used in your graphics: you determine where your contour function and the region function have common points. Due to the high symmetry of your equation, let me propose the following:

eq = {1/2*(x^2 + y^2 + z^2) + (x^2*y^2 + x^2*z^2 + y^2*z^2 -
x^2*y^2*z^2) == E0,
Sqrt[x^2*y^2 + x^2*z^2 + y^2*z^2] == 4} /. {z :> x};

pt = Mean[Select[
Chop[N[{x, y, x} /. Solve[eq, {x, y}]]],
FreeQ[#, Complex] && Min[#] > 0 &]];

midPoints = pt*# & /@ Tuples[{-1, 1}, {3}];


This results in the following midPoints which you could use as label positions

• Nice approach! BTW, what's the exact ViewPoint you used? Sep 30, 2013 at 7:44
• @Vaggelis_Z For the first graphic it is {0.0653668, -3.25175, 0.933735} and for the second one it is {0.553949, 1.15298, 3.13269}. But I haven't done anything special! I just rotated the graphics a bit so that I liked the view. Sep 30, 2013 at 11:54