# Piecewise ColorFunction fails

I have Mathematica 10.3, and when I run

MyColorFunc[z_] := Piecewise[{{Blue, z > 0}, {Green, z == 0}, {Red, z < 0}}];
f[x_, y_] := x^2 + y^2 - 3;
Plot3D[f[x, y], {x, -2, 2}, {y, -2, 2}, ColorFunction -> MyColorFunc,
PlotRange -> All]


the entirety of the plot is blue, apart from a spot where it's green (at 0,0 where it should really be blue).

Is this a bug in my version, or I am doing something wrong? I have similar issues with ContourPlot.

• Related, perhaps a duplicate: (55278) Jun 8, 2018 at 9:52

You probably want

Plot3D[f[x, y], {x, -2, 2}, {y, -2, 2}, MeshFunctions -> {#3 &},
Mesh -> {{0}}, MeshStyle -> {Directive[Thick, Green]},
MeshShading -> {Red, Blue}, PlotRange -> All] Alternatively,

Plot3D[Evaluate[ConditionalExpression[f[x, y], #] & /@ {f[x, y] <= 0,
f[x, y] > 0}], {x, -2, 2}, {y, -2, 2}, PlotStyle -> {Red, Blue},
Mesh -> None, BoundaryStyle -> {1 -> Directive[Thick, Green], 2 -> None}] Compare with what you get with ColorFunction (note the absence of Green line and the blending of Red and Blue at the boundary):

Plot3D[f[x, y], {x, -2, 2}, {y, -2, 2}, ColorFunction -> MyColorFunc,
PlotRange -> All, ColorFunctionScaling -> False] Update: We can eliminate the blending using Exclusions -> {f[x,y] == 0} and use the option ExclusionsStyle to color the boundary between the two pieces:

Plot3D[f[x, y], {x, -2, 2}, {y, -2, 2},
Exclusions -> {f[x, y] == 0},
ExclusionsStyle -> Directive[Thick, Green],
ColorFunction -> MyColorFunc, PlotRange -> All,
ColorFunctionScaling -> False] • Beautiful, thanks, Feb 14, 2018 at 8:49
• @ThreeDiag, my pleasure.
– kglr
Feb 14, 2018 at 9:14

With ColorFunctionScaling -> True (the default), 1D color functions are scaled to the domain [0,1]. cf[z_] := Piecewise[{{Blue, z > 1/2}, {Green, z == 1/2}, {Red, z < 1/2}}] colors the lower half red and the upper half blue.

With ColorFunctionScaling -> False, the actual z value is used instead, allowing the original function to work (likely as you intended).

• Thanks, you are right. I've stumbled upon a similar post a Second before you answered, so my q is likely a duplicate, but thanks =) Feb 14, 2018 at 8:45
• @ThreeDiag If it is a duplicate or another question helped you out, it'd be good to link the other question so that other people can find it more easily. Even if this question ends up getting closed, there's no harm in having the additional information available. Feb 14, 2018 at 9:33

Define the function with MyColorFunc[args__].

Try using ColorFunction -> (MyColorFunc[##]&).

According to the documentation, the arguments are scaled versions of the $x$, $y$ and $z$ coordinates.

Since you've already gotten some great answers that touch upon the importance of ColorFunctionScaling -> False, let me just demonstrate another method for the kind of coloring you want to do:

myColorFunction = Blend[{ColorData[{"ThermometerColors", "Reverse"},
LogisticSigmoid[80 #]],
Green}, Exp[-80 #^2]] &;


where we use a sigmoid to map $(-\infty,\infty)$ to $(0,1)$ for ColorData[], and use a sharply peaked Gaussian along with Blend[] to insert the green color at $0$. With this,

Plot3D[x^2 + y^2 - 3, {x, -2, 2}, {y, -2, 2},
ColorFunction -> (myColorFunction[#3] &), ColorFunctionScaling -> False,
Mesh -> False, PlotPoints -> 105, PlotRange -> All] 