I'm still new to plotting in Mathematica and have been trying to figure out how to overlay a single color (white) over a color gradient (in this case rainbow) to highlight a range of values in a plot I generated with a mathematical function. I though this would be relatively straightforward since it appeared similar to several other questions asked here (especially this one: Impose the color for one discrete value above a color predefined gradient), but the methodology that the person presented did not solve my problem. This is the original ArrayPlot with the rainbow gradient
enter image description here

I want to highlight a range (say 2-3) with white and if I apply the method used in the linked post by defining a custom colorfunction like

cf = If[(2 <= # <= 3), White, Blend["Rainbow", #]] &;

and then apply it to the same array

ArrayPlot[a, PlotLegends -> Automatic, 
 ClippingStyle -> Automatic, ColorFunction -> cf, AspectRatio -> 2, 
 ColorFunctionScaling -> False]

Then I get the following image
enter image description here

The area I want is highlighted but it doesn't fit in nicely in the rainbow colorfunction as desired and as it seemed to for the previous question. If I do not use the ColorFunctionScaling->False option I get no change to the plot at all. I will note that I tried the other method in that post as well defining a piecewise function and got similar results. I also tried using ColorRule and it worked okay for one value (say 2=white), but I tried several methods for feeding it a range of values and that yield similar results to the second image.

Any insight would be appreciated


1 Answer 1

data = N @ Table[Rescale[Sin[j^2 + i], {-1, 1}, {0, 6}], 
   {i, 0, Pi, Pi/100}, {j, 0, Pi, Pi/100}];

1. Define your color function as:

cfa = If[2 <= # <= 3, White, ColorData[{"Rainbow", MinMax @ data}] @ #] &;

Compare ColorFunction -> "Rainbow" versus ColorFunction -> cfa + ColorFunctionScaling -> False:

ap = ArrayPlot[data, PlotLegends -> Automatic, 
   ColorFunction -> "Rainbow", ImageSize -> 400];

apa = ArrayPlot[data, PlotLegends -> Automatic, ColorFunction -> cfa, 
   ColorFunctionScaling -> False, ImageSize -> 400];

Row[{ap, apa}, Spacer[10]]

enter image description here

Extract and resize the two legends to get a closer look:

Row[#[[2, 1]] & /@ {ap, apa} /. 
    HoldPattern[ LegendMarkerSize -> _] :> LegendMarkerSize -> {100, 400}]

enter image description here

2. Alternatively, you can define the color function as

cfb = If[2 <= # <= 3, White, Blend["Rainbow", Rescale[#, MinMax @ data]]] &;

We get the same picture using cfa and cfb:

apb = ArrayPlot[data, PlotLegends -> Automatic, ColorFunction -> cfb, 
   ColorFunctionScaling -> False, ImageSize -> 400];

Row[{apa, apb}, Spacer[10]]

enter image description here

3. Yet another alternative is to define the color function rescaling the threshold values and remove the option ColorFunctionScaling -> False:

cfc = If[Rescale[2, MinMax @ data] <= # <= Rescale[3, MinMax @ data], White, 
   Blend["Rainbow", #]] &;

apc = ArrayPlot[data, PlotLegends -> Automatic, ColorFunction -> cfc, 
   ImageSize -> 400];

Row[{apa, apc}, Spacer[10]]

enter image description here


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.