# Overlaying a single color with a colorfunction on a MatrixPlot or ArrayPlot to highlight certain values

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

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

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

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


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

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


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


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