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.
3 Answers
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]
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.
-
$\begingroup$ Nice, and one could change that
Switch
to take theColorData
of the underlying contour plot too. Might need aLighter@*
on it too so it doesn't wholly blend in I guess. $\endgroup$– b3m2a1Commented Mar 12, 2017 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$– simonCommented Mar 12, 2017 at 21:21
-
$\begingroup$ @simon - look at the documentation for
Function
andSlot
. Links include in edit above. $\endgroup$ Commented Mar 12, 2017 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$ Commented Mar 13, 2017 at 4:49 -
$\begingroup$ @Mr.Wizard - this approach is not particularly robust but tailoring is straightforward. $\endgroup$ Commented Mar 13, 2017 at 5:42
Another way to use post-processing is to take advantage of the Tooltip
s 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]
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}} &;
* Is there a way to access the (lexically) current colour inside Graphics?
-
$\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$ Commented Mar 13, 2017 at 4:54
-
$\begingroup$ @Mr.Wizard, much nicer, thank you. Makes me think "what was i thinking?" $\endgroup$– kglrCommented Mar 13, 2017 at 5:05
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