Reverse GrayLevel (not same as GrayTones)

I'm trying to make a color bar with reverse GrayLevel, i.e, like bl1 below, but reversed. bl2 gets quite close, but the white end isn't quite maxed out, it looks slightly grey. I tried the trick from a few other posts on similar topic, but I can't get the range right. What am I missing?

Row[{
bl1 = BarLegend[{GrayLevel, {-0.1, 0.1}}],
bl2 = BarLegend[{{"GrayTones", "Reverse"}, {-0.1, 0.1}}],
bl3 = BarLegend[{ColorData["GrayTones"][1 - #] &, {-0.1, 0.1}}],
bl4 = BarLegend[{ColorData[GrayLevel][1 - #] &, {-0.1, 0.1}}]
}]


• ColorData[GrayLevel] is never going to work. You wanted BarLegend[{ColorData[GrayLevel][1 - #] &, {-0.1, 0.1}}] Commented Feb 4, 2020 at 19:31

I use Blend[{White, Black}, #1] &

Row[{
bl1 = BarLegend[{GrayLevel, {-0.1, 0.1}}],
bl2 = BarLegend[{{"GrayTones", "Reverse"}, {-0.1, 0.1}}],
bl3 = BarLegend[{Blend[{White, Black}, 5 # + 0.5] &, {-0.1, 0.1}}],
bl4 = BarLegend[{Blend[{Black, White}, 5 # + 0.5] &, {-0.1, 0.1}}]
}]


• Nice solution @Young . And for any range can use for example: With[{a = 0.1}, BarLegend[{Blend[{White, Black}, 0.5/a # + 0.5] &, {-a, a}}]] Commented Sep 15, 2016 at 3:10
Row[{
BarLegend[{{White, Black}, {-0.1, 0.1}}],
BarLegend[{GrayLevel[1 - #] &, {-0.1, 0.1}}, ColorFunctionScaling -> True]
}]


None of the other answers mention this, so:

1. For a color scheme like "GrayTones" that belongs to the list ColorData["Gradients"], one can modify them so that they have a different range from the default of $$[0,1]$$. In this case, if the dark color of "GrayTones" (ColorData["GrayTones"][0]) should correspond to 0.1, and the light color of "GrayTones" (ColorData["GrayTones"][1]) should correspond to -0.1, then one should use something like ColorData[{"GrayTones", {0.1, -0.1}}].

2. Functions like GrayLevel[] and Hue[] do not have this functionality. Thus, one has to use the built-in function specifically designed for the task, Rescale[]. Since one wants a mapping from {-0.1, 0.1} to {1, 0} (note the order!), then GrayLevel should be composed with Rescale[x, {-0.1, 0.1}, {1, 0}].

Thus:

Row[{bl1 = BarLegend[{GrayLevel, {-0.1, 0.1}}],
bl2 = BarLegend[{{"GrayTones", "Reverse"}, {-0.1, 0.1}}],
bl3 = BarLegend[{ColorData[{"GrayTones", {0.1, -0.1}}], {-0.1, 0.1}}],
bl4 = BarLegend[{ColorData["GrayTones", Rescale[#, {-0.1, 0.1}, {1, 0}]] &,
{-0.1, 0.1}}],
bl5 = BarLegend[{GrayLevel[Rescale[#, {-0.1, 0.1}, {1, 0}]] &, {-0.1, 0.1}}]}]


and we see that the middle three gradients are equivalent.

As a more striking example of the utility of Rescale[]:

Row[{BarLegend[{Hue, {-0.1, 0.1}}],
BarLegend[{Hue[Rescale[#, {-0.1, 0.1}, {1, 0}]] &, {-0.1, 0.1}}]}]


• JM, this is awesome, great explanation and presentation of such a simple way to do what can be so easily over complicated. In terms of over complicating things, can you clarify if there is an easy way to have this “autoscale” to the given bounds? Or am I overlooking something? Commented Feb 5, 2020 at 4:34