I need to generate a 3D plot of a function, say $z = \sin(x)\cos(y)$, with contour lines drawn at specified intervals. I also want to label each contour line with its $z$-value. I have discovered how to superimpose the contour lines on the 3D graph thanks to this post: Adding contour lines to a 3D plot?. However, I still cannot figure out how to label these contour lines with their $z$-values. How can this be done?


1 Answer 1


Here is an approach exploiting the underlying graphics objects calculation of the contours (in this case level curves):

contlab[f_, {x0_, x1_}, {y0_, y1_}, cont_, fntsize_, fntwt_, 
  opts : OptionsPattern[]] :=
 Module[{p, pts, ct, txt, pos, ptnum, txtpos, txtval},
  p = Plot3D[f, {x, x0, x1}, {y, y0, y1}, MeshFunctions -> (#3 &), 
    Mesh -> {cont}, Evaluate@FilterRules[{opts}, Options[Plot3D]]];
  pts = p[[1, 1]];
  ct = Rest@Cases[p, Line[x__] :> x, Infinity];
  pos = Floor[Length[#]/2] & /@ ct;
  ptnum = MapThread[#1[[#2]] &, {ct, pos}];
  txtpos = pts[[#]] & /@ ptnum;
  txtval = Last /@ txtpos;
  txt = MapThread[
    Text[Style[#1, fntsize, fntwt], #2] &, {txtval, txtpos}];
  Show[Graphics3D[txt], p]]

This is just an approach and particular stylistic preferences could be adapted:

contlab[Cos[y] Sin[x], {-2, 2}, {-2, 2}, {0.2`, 0.5`, 0.75`, 
  0.9`}, 12, Bold, MeshStyle -> {Thickness[Large], RGBColor[1, 0, 0]}]


enter image description here

The graphic structure is such that the contours are stored as Line[] after the lines of the boundary of the plot. I have taken account of possible multiple contours for given value and no contour by using the values from lines available. Doubtless there will be exceptional cases but this is an approach.


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.