4
$\begingroup$

I am using ContourPlot3D to show two surfaces. This is my code. Now I want to use Legend to distinguish the two surfaces, and add arrowhead for the three axis.

sf1[x_, y_, z_] := x  (1/(1 + 0.06))^3 + y (1/(1 + 0.06))^2 - z/3;
sf2[x_, y_, z_] := x  (1 + 5 0.06) (1/((1 + 5 0.06) + 0.06))^3 + y (1 + 5 0.06) (1/((1 + 5 0.06) + 0.06))^2 - z/3;
ContourPlot3D[{sf1[x, y, z] == 0, sf2[x, y, z] == 0}, {x, 0, 150}, {y, 0, 100}, {z, 0, 200}, Ticks -> None, AxesLabel -> {"x", "y", "z"}, BoundaryStyle -> Red, Boxed -> False, AxesOrigin -> {0, 0, 0}]

I have try PlotLegends, and AxesStyle in the following code. As you can see, the using of PlotLegends does not distinguish them very well. And the AxesStyle can not add anything for the axis. I recognized the "axis" I mentioned is actually frame in ContourPlot3D, but how can I use axis rather than frame in ContourPlot3D? Thanks in advance!

ContourPlot3D[{sf1[x, y, z] == 0, sf2[x, y, z] == 0}, {x, 0, 150}, {y, 0, 100}, {z, 0, 200}, Ticks -> None, AxesLabel -> {"x", "y", "z"}, BoundaryStyle -> Red, Boxed -> False, AxesOrigin -> {0, 0, 0}, PlotLegends -> {"b=0", "b=5"}, AxesStyle -> Arrowheads[{0.0, 0.03}] ]
$\endgroup$
  • $\begingroup$ for arrowheads on axes see: traditional axes in 3d mathematica plots $\endgroup$ – kglr Nov 6 '14 at 8:51
  • 1
    $\begingroup$ What don't you like about the legend, exactly? I see the shadows as being a major issue, in that from some angles the contour surfaces are too dark and don't resemble the swaths from the legend. One way to fix this is to add Lighting -> {{"Ambient", White}} to the ContourPlot3D function. $\endgroup$ – Jason B. Nov 6 '14 at 9:56
5
$\begingroup$

Try this:

    sf1[x_, y_, z_] := x (1/(1 + 0.06))^3 + y (1/(1 + 0.06))^2 - z/3;
sf2[x_, y_, z_] := 
  x (1 + 5 0.06) (1/((1 + 5 0.06) + 0.06))^3 + 
   y (1 + 5 0.06) (1/((1 + 5 0.06) + 0.06))^2 - z/3;


Show[{
  ContourPlot3D[{sf1[x, y, z] == 0, sf2[x, y, z] == 0}, {x, 0, 
    150}, {y, 0, 100}, {z, 0, 200}, Ticks -> None, 
   BoundaryStyle -> Red, Boxed -> False, AxesOrigin -> {0, 0, 0}],
  Graphics3D[{Red, Thickness[0.005], Arrowheads[0.03], 
    Arrow[{{0, 0, 0}, {153, 0, 0}}], Arrow[{{0, 0, 0}, {0, 0, 203}}], 
    Arrow[{{0, 0, 0}, {0, 102, 0}}]}],
  Graphics3D[{Text[
     Style["x", 18, Italic, Bold, 
      FontFamily -> "Times New Roman"], {149, 0, 16}], 
    Text[Style["y", 18, Italic, Bold, 
      FontFamily -> "Times New Roman"], {0, 96, 22}], 
    Text[Style["z", 18, Italic, Bold, 
      FontFamily -> "Times New Roman"], {0, 0, 215}]}]
  }]

It should give this:

enter image description here

With another ViewPoint though. I turned a bit to make the y axis visible.

Have fun!

Edit: to address your question. I also did not succeed to use the Epilog->Insetstructure for this purpose. However, you may simply draw the necessary objects "by hand" the same way as the axes and labels were drawn. Try this:

  Show[{ContourPlot3D[{sf1[x, y, z] == 0, sf2[x, y, z] == 0}, {x, 0, 
    150}, {y, 0, 100}, {z, 0, 200}, Ticks -> None, 
   BoundaryStyle -> Red, Boxed -> False, AxesOrigin -> {0, 0, 0}, 
   ViewPoint -> {1.54, -2.77, 1.19}], 
  Graphics3D[{Red, Thickness[0.005], Arrowheads[0.03], 
    Arrow[{{0, 0, 0}, {153, 0, 0}}], Arrow[{{0, 0, 0}, {0, 0, 203}}], 
    Arrow[{{0, 0, 0}, {0, 102, 0}}]}], 
  Graphics3D[{Text[
     Style["x", 18, Italic, Bold, 
      FontFamily -> "Times New Roman"], {149, 0, 16}], 
    Text[Style["y", 18, Italic, Bold, 
      FontFamily -> "Times New Roman"], {0, 96, 22}], 
    Text[Style["z", 18, Italic, Bold, 
      FontFamily -> "Times New Roman"], {0, 0, 215}],
    Text[Style["b=0", 20, Darker@Brown], {20, 20, 180}],
    Text[Style["b=5", 20, Darker@Blue], {83, 47, 128}]
    }],
  Graphics3D[{Arrowheads[0.03], Thickness[0.005], 
    Arrow[{{20, 20, 173}, {25, 25, 129}}], 
    Arrow[{{83, 47, 132}, {74, 34, 188}}]}]
  }]

you should obtain the following:

enter image description here

The advantage is that bot the letters and arrows are 3D objects and you may rotate the image to visualize, say, where the second arrow points to. If the image rotation is not necessary, you may think about playing with the coordinates and placing the text b=5and the corresponding arrow into another position, where the arrow is more visible.

Have fun!

$\endgroup$
  • $\begingroup$ @ Alexei Boulbitch. Thanks your answer is very helpful! Could you give me some advice on adding some text in the 3D plot to distinguish the two planes? I have tried Epilog -> {Inset["b=0", {10, 50}], Inset["b=5", {50, 50}]}. But it doesn't work in the 3D case. Is there any possible to use Graphics3D or to use different surface mesh to distinguish them? Thanks a lot! $\endgroup$ – Enter Nov 7 '14 at 3:12
  • $\begingroup$ @ Alexei Boulbitch. Thanks! I have learned the Graphics3D from you :-P $\endgroup$ – Enter Nov 7 '14 at 10:47
3
$\begingroup$

Modifying the function axes in this answer:

axes3D[x_, y_, z_, f_, a_] := With[{min = Min[x, y, z]},
  Graphics3D[Join[{Arrowheads[a]}, Arrow[{{0, 0, 0}, #}] & /@ {{x, 0, 0}, {0, y, 0}, {0, 0, z}},
    Text[Style[#, FontSize -> Scaled[f]], #2] & @@@
     Transpose[{{"x", "y", "z"}, {{x/2, 0, 0}, {0, y/2, 0}, {0, 0, z/2}} /. (0) -> (-.05 min)}]],
   Boxed -> False]]

cp = ContourPlot3D[{sf1[x, y, z] == 0, sf2[x, y, z] == 0}, {x, 0, 150}, {y, 0, 100}, {z, 0, 200},
   BoundaryStyle -> Red, ContourStyle -> {Directive[Opacity[.8], Yellow], 
     Directive[Opacity[.8], Green]}, Mesh -> None, 
   PlotLegends -> SwatchLegend[{Yellow, Green}, {"b=0", "b=5"}]];

Show[axes3D[##&@@(Last/@ PlotRange[cp[[1]]]), .05, .03], cp, BoxRatios -> 1, Lighting -> "Neutral"]

enter image description here

$\endgroup$
  • $\begingroup$ @ kguler, Thanks for your help! I tried Epilog -> {Inset["b=0", {10, 50}], Inset["b=5", {50, 50}]}. But it doesn't work in the 3D framework. Is there any other method to use Graphics3D or to use different surface mesh to distinguish them? Because I need black-white picture in a report, I prefer to use the text and graphs, i.e. different mesh, to distinguish them. Thanks in advance!! $\endgroup$ – Enter Nov 7 '14 at 3:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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