7
$\begingroup$

ContourPlot picks a nice set of curves as level curves by default. I'm trying to use the set of curves as mesh curves for corresponding 3D plot, can anyone suggest how I can get those levels extracted out of contour plot?

f[x_, y_] := Log[(1 - x)^2 + 100 (y - x^2)^2];
ContourPlot[f[x, y], {x, -2, 0.5}, {y, -2, 2}, 
 ContourStyle -> {{Gray, Thick}}, PlotPoints -> 100, 
 ColorFunction -> Function[GrayLevel[1 - .45 #]], Frame -> None]
Plot3D[f[x, y], {x, -2, 0.5}, {y, -2, 2}, PlotPoints -> 100, 
 MeshFunctions -> {#3 &}, Mesh -> {{0, 1, 2, 3, 4}}, Ticks -> None]

enter image description here

$\endgroup$
5
  • $\begingroup$ You can hunt through for Tooltips $\endgroup$
    – Jason B.
    Commented Dec 13, 2017 at 17:49
  • $\begingroup$ Hm...tooltips says the curves are 0,1,2,3,4,5,6,7,8....but using those as Mesh values doesn't give me same curves $\endgroup$ Commented Dec 13, 2017 at 17:56
  • $\begingroup$ I can't reproduce that - if I change the code you posted, and add in the 5,6,7, and 8, it looks the same as below $\endgroup$
    – Jason B.
    Commented Dec 13, 2017 at 18:04
  • $\begingroup$ ok looks like I was plotting 2 different functions, thanks for the Tooltip extractor code $\endgroup$ Commented Dec 13, 2017 at 19:05
  • $\begingroup$ Duplicates: (31858), (66487) $\endgroup$
    – Michael E2
    Commented Dec 14, 2017 at 12:36

2 Answers 2

9
$\begingroup$

By default, contours generated by ContourPlot have Tooltips with their numerical value as the label. You can use Cases to grab the values programmatically.

f[x_, y_] := Log[(1 - x)^2 + 100 (y - x^2)^2];
plot = ContourPlot[f[x, y], {x, -2, 0.5}, {y, -2, 2}, 
  ContourStyle -> {{Gray, Thick}}, PlotPoints -> 100, 
  ColorFunction -> Function[GrayLevel[1 - .45 #]], Frame -> None]

levels = Union@Cases[plot, Tooltip[_, label_] :> label, Infinity];

Plot3D[f[x, y], {x, -2, 0.5}, {y, -2, 2}, PlotPoints -> 100, 
 MeshFunctions -> {#3 &}, Mesh -> {levels}, Ticks -> None]

enter image description here

$\endgroup$
3
$\begingroup$
ContourPlot[f[x, y], {x, -2, .5}, {y, -2, 2}, 
   Contours -> ((contours = FindDivisions[{#, #2}, #3, Method -> {}]) &)];
Plot3D[f[x, y], {x, -2, .5}, {y, -2, 2}, PlotPoints -> 100, 
  MeshFunctions -> {#3 &}, Mesh -> {contours}, Ticks -> None]

enter image description here

Jason's approach, extracting Tooltip labels form ContourPlot output, is straightforward and convenient.

For the curious, how ContourPlot picks a nice set of curves as level curves by default remains a puzzle.

Speaking of "nice", searching for "nice numbers" in the Documentation Center gives: enter image description here

See also: Google Search: wolfram documentation "nice" numbers.

Documentation >> FindDivisions: enter image description here enter image description here Documentation >> Contours: enter image description here

After a few trials, we find that the function FindDivisions[{#, #2}, #3, Method -> {}]& (where the first two arguments are $z_{min}$ and $z_{max}$ and the last argument is the number of divisions which is fixed at 10) as the setting for Contours gives the same output as the default setting for this option.

Some examples:

ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}] == 
 ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}, 
  Contours -> (FindDivisions[{#, #2}, #3, Method -> {}] &)] ==
 ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}, 
  Contours -> (FindDivisions[{#, #2}, 10, Method -> {}] &)]

True

rr = RandomReal[5, 2];
ContourPlot[Evaluate[Sum[Sin[rr.{x, y}], {5}]], {x, 0, 5}, {y, 0, 5}] == 
 ContourPlot[Evaluate[Sum[Sin[rr.{x, y}], {5}]], {x, 0, 5}, {y, 0, 5},
   Contours -> (FindDivisions[{#, #2}, #3, Method -> {}] &)]

True

So for OP's example, we can extract the default contour levels using this function as follows:

f[x_, y_] := Log[(1 - x)^2 + 100 (y - x^2)^2];
cp1 = ContourPlot[f[x, y], {x, -2, .5}, {y, -2, 2}];
levels = Cases[cp1, Tooltip[_, t_]:>t, Infinity];

cp2 = ContourPlot[f[x, y], {x, -2, .5}, {y, -2, 2}, 
   Contours -> ((contours = FindDivisions[{#, #2}, #3, Method -> {}]) &)];

cp1 === cp2

True

levels == Reverse@contours

True

$\endgroup$

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.