12
$\begingroup$

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}}]
}]

Out

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

3 Answers 3

12
$\begingroup$

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}}]
  }]

enter image description here

$\endgroup$
1
  • $\begingroup$ 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}}]] $\endgroup$
    – DrBubbles
    Sep 15, 2016 at 3:10
4
$\begingroup$
Row[{
  BarLegend[{{"MonochromeFractalGradient", "Reverse"}, {-0.1, 0.1}}],
  BarLegend[{{White, Black}, {-0.1, 0.1}}],
  BarLegend[{GrayLevel[1 - #] &, {-0.1, 0.1}}, ColorFunctionScaling -> True]
  }]

Out

$\endgroup$
2
$\begingroup$

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}}]}]

bar legends with grayscale gradients

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}}]}]

HSB gradient and its reverse

$\endgroup$
1
  • $\begingroup$ 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? $\endgroup$ Feb 5, 2020 at 4:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.