7
$\begingroup$

My show is an overlay of 3 sets of countours in 3 different colours, but the countour labels are all black which makes identification problematic. I don't seem to be able to find a way to make the countour labels the same colour as their contours.

$\endgroup$
  • 2
    $\begingroup$ You need to post in a code block the executable code that demonstrates the problem you are trying to resolve. $\endgroup$ – Bob Hanlon Mar 11 '17 at 21:59
6
$\begingroup$
ContourPlot[
 Sin[x] Sin[y],
 {x, -3, 3}, {y, -3, 3},
 ContourStyle -> {Red, Dashed, Green},
 ContourLabels ->
  (Text[Style[#3,
      Switch[#3,
       -0.8 | -0.2 | 0.4, Red,
       -0.6 | 0 | 0.6, Black,
       -0.4 | 0.2 | 0.8, Green]],
     {#1, #2}] &),
 BaseStyle -> 18]

enter image description here

EDIT: If the pure Function using Slot designations is difficult to read, you can write this as

ContourPlot[
 Sin[x] Sin[y],
 {x, -3, 3}, {y, -3, 3}, 
 ContourStyle -> {Red, Dashed, Green}, 
 ContourLabels ->
  Function[{x, y, contourValue},
   Text[Style[contourValue,
     Switch[contourValue,
      -0.8 | -0.2 | 0.4, Red,
      -0.6 | 0 | 0.6, Black,
      -0.4 | 0.2 | 0.8, Green]],
    {x, y}]],
 BaseStyle -> 18]

EDIT 2: The default number of contour lines is nine. The contour lines will occur at function values of

lines = Module [{fmin = -1., fmax = 1., fdel},
  fdel = (fmax - fmin)/10;
  Range[fmin + fdel, fmax - fdel, fdel] // Chop]

(*  {-0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8}  *)

For a cycle of three colors, the groupings will be

With[{numberOfColors = 3},
 Partition[lines, numberOfColors] // Transpose]

(*  {{-0.8, -0.2, 0.4}, {-0.6, 0, 0.6}, {-0.4, 0.2, 0.8}}  *)

This will obviously change for different function ranges, number of contours, and number of colors.

$\endgroup$
  • $\begingroup$ Nice, and one could change that Switch to take the ColorData of the underlying contour plot too. Might need a Lighter@* on it too so it doesn't wholly blend in I guess. $\endgroup$ – b3m2a1 Mar 12 '17 at 16:27
  • $\begingroup$ Great. That code worked pasted in and does more than I need. Sorry I don't understand it enough to modify it to just do the contours all in Red and the contour labels in Red too as I want with my function.It is the # stuff I don't get, Simon $\endgroup$ – simon Mar 12 '17 at 21:21
  • $\begingroup$ @simon - look at the documentation for Function and Slot. Links include in edit above. $\endgroup$ – Bob Hanlon Mar 12 '17 at 23:01
  • $\begingroup$ I entertained this approach but I do not see how to find the values -0.8 | -0.2 | 0.4 etc. robustly, without turning to post-processing again. Any ideas? $\endgroup$ – Mr.Wizard Mar 13 '17 at 4:49
  • $\begingroup$ @Mr.Wizard - this approach is not particularly robust but tailoring is straightforward. $\endgroup$ – Bob Hanlon Mar 13 '17 at 5:42
5
$\begingroup$

Another way to use post-processing is to take advantage of the Tooltips that are automatically generated by ContourPlot when the option ContourLabels is not used:

addColoredLabels = # /. 
    Tooltip[{x___, l : Line[__] ..}, z_] :> {x, l, 
      Dynamic@Text[Style[z, Darker@Darker@CurrentValue["Color"]], RandomChoice[#[[1]]],
           Background -> Opacity[.5, Lighter@Lighter@CurrentValue["Color"]]] & /@ {l}} &;

Example:

addColoredLabels @ ContourPlot[Sin[x] Sin[y], {x, -3, 3}, {y, -3, 3}, 
   ContourStyle -> ColorData[3, "ColorList"], 
   BaseStyle -> {Thick, 18, Bold}, ImageSize -> 500] 

Mathematica graphics

A simpler version of that function without the arcane CurrentValue["Color"]*.

colorSimple = # /. 
    Tooltip[{x___, l__Line}, z_] :> {x, l, 
       Text[Style[z, Opacity[1]], RandomChoice @@ #] & /@ {l}} &;

enter image description here

* Is there a way to access the (lexically) current colour inside Graphics?

$\endgroup$
  • $\begingroup$ Nice solution! Surely safer than mine. But I think you obfuscate it too much. I am going to add a simpler version for those who have trouble following the first code. $\endgroup$ – Mr.Wizard Mar 13 '17 at 4:54
  • $\begingroup$ @Mr.Wizard, much nicer, thank you. Makes me think "what was i thinking?" $\endgroup$ – kglr Mar 13 '17 at 5:05
4
$\begingroup$

There does not appear to be any way to do this natively. Here is an attempt at a post-processing work-around:

syncCountourLabels[g : Graphics[_GraphicsComplex, ___]] :=
  Module[{text, i = 1, pos = FirstPosition[g, {__Text}]},
   (
    text = Reverse @ Extract[g, pos];
    Delete[g, pos] /. x_Line :> {x, {Opacity[1], text[[i++]]}}
    ) /; pos =!= Missing["NotFound"]
  ]

Example:

ContourPlot[
  Sin[x] Sin[y], {x, -3, 3}, {y, -3, 3}, 
  ContourStyle -> {Red, Dashed, Green},
  ContourLabels -> True, 
  BaseStyle -> 18
] // syncCountourLabels

enter image description here

$\endgroup$

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.