Plot3D: ColorFunction depending on (x,y) or z [closed]

While trying to answer this question I found out "weird" behavior of ColorFunction

Plot3D[x y, {x, -10, 10}, {y, -10, 10}, PlotRange -> Full,
ColorFunction -> Function[{x, y, z}, Hue@(x y)]]


gives incorrect colors

the virtually identical code (from naive point of view)

Plot3D[x y, {x, -10, 10}, {y, -10, 10}, PlotRange -> Full,
ColorFunction -> Function[{x, y, z}, Hue@z]]


gives correct plot

Also if you disable ColorFunctionScaling as many posts (e.g. this) suggest

Plot3D[x y, {x, -10, 10}, {y, -10, 10}, PlotRange -> Full,
ColorFunction -> Function[{x, y, z}, Hue@(x y)],
ColorFunctionScaling -> False]


the colors are really messed up

So the question - why are the first two plots different? A bug?

I'm using Mathematica 11.1 on Linux.

• The third plot only looks messed up because you're using too few PlotPoints (or too large a $xy$ range). You're correct in that ColorFunctionScaling is the issue for the first two plots, they are scaled differently, as is clear from the documentation. – Roman Apr 30 '19 at 17:12
• @Roman Why are the first two plots scaled differently? They both have ColorFunctionScaling  true. Also z=xy so Hue[z] should be same as Hue[xy] – BlacKow Apr 30 '19 at 18:44
• In the first plot, both $x$ and $y$ are scaled to the range $[0,1]$ and thus $x y$ (meaning the product of scaled-$x$ and scaled-$y$) is zero in the lower-left corner, left edge, and lower edge, and 1 in the upper-right corner. In the second plot, $z$ is scaled to the range $[0,1]$ and thus zero in the lower-right and upper-left corners, and 1 in the lower-left and upper-right corners. If you play with Hue@x, Hue@y, and Hue@z both with and without ColorFunctionScaling it all becomes clear. – Roman Apr 30 '19 at 18:53
• From the documentation: "ColorFunctionScaling is an option for graphics functions that specifies whether arguments supplied to a color function should be scaled to lie between 0 and 1." Meaning that every argument of the color function will be scaled to $[0,1]$. – Roman Apr 30 '19 at 19:04
• @Roman OK, I see it now.. somehow I wrongfully assumed that the ColorFunctionScaling controls the scaling of the value, not arguments. Honestly I'm not sure what's the point of scaling arguments to [0,1]. If you make it an answer I will gladly accept. Thanks! – BlacKow Apr 30 '19 at 19:08

As the documentation on ColorFunctionScaling says,
In the first plot, $$x$$ and $$y$$ are both scaled to the range $$[0,1]$$. This means that the ColorFunction does not receive $$x$$ and $$y$$, but rather $$(x+10)/20$$ and $$(y+10)/20$$, and the color is then the hue of $$(x+10)(y+10)/400$$.
In the second plot, $$z$$ is scaled to the range $$[0,1]$$. This means that the ColorFunction does not receive $$z$$, but rather $$(z+100)/200$$ as the third argument.
In the third plot, the number of PlotPoints is too small and thus you see Moiré effects.
• Increasing PlotPoints make it smoother, but you need to go with manually scaled ColorFunction -> Function[{x, y, z}, Hue[0.01 x y]] to make a desired effect. – BlacKow Apr 30 '19 at 19:22