# Engineering a colour scale for MatrixPlot

I am trying to find the best way to plot my data. I have a 2D list of scalar coefficients (rational numbers) whose value lies between 0 and 1 (being rational, they can be 0,..., 0.01,... 0.999,..., 1). I want to plot the amplitude of these coefficients in 2D and use a colour function to indicate their amplitude.

I think the best way to do this is to use

MatrixPlot[]


with options

ColorFunction -> "MyPersonalScheme"


and (possibly?)

ColorFunctionScaling -> True


In essence, my question is the following:

"How can I engineer a color scheme, "MyPersonalScheme", so that a coefficient of amplitude 0 is plotted in white, and a coefficient of amplitude 1 is plotted in red (and have a 'hue' of colour from white to red for amplitudes in between)?"

In general, one uses Blend[] to construct custom color schemes.

BlockRandom[SeedRandom; (* for reproducibility *)
mat = RandomReal[1, {50, 50}]];


Here is how to use Blend[] with ArrayPlot[]:

ArrayPlot[mat, ColorFunction -> (Blend[{White, Red}, #] &), ColorFunctionScaling -> False] (Something similar could be done for MatrixPlot[], but you might want to be aware that it downsamples by default.)

In fact, since one of your colors is White, there is an even simpler way to generate the same plot, using Lighter[]:

ArrayPlot[mat, ColorFunction -> (Lighter[Red, 1 - #] &), ColorFunctionScaling -> False]


Finally, the simplest method for this case would be the direct use of RGBColor[]:

ArrayPlot[mat, ColorFunction -> (RGBColor[1, 1 - #, 1 - #] &),
ColorFunctionScaling -> False]

• thanks a lot, this really helps. I understand how you build your color scheme. Two questions: 1) one on what you did - why do you set ColorFunctionScaling to False? I understand this passes the matrix values to the color function without any scaling, but how would one decide between one and another. 2) What do you mean by "downsampling"?
– MXJ
Sep 20 '17 at 16:48
• Setting ColorFunctionScaling to False ensures that it is your actual data, and not a rescaled version of it, that gets fed to the ColorFunction setting. In this case, the matrix entries are in the interval $[0, 1]$, so a direct feed is appropriate. If you have entries outside that range, then you need ColorFunctionScaling -> True. Sep 22 '17 at 12:11
• As for the downsampling: look at the docs of MatrixPlot[] for details, but in brief, that only plots a subset of your matrix values if the matrix's size is large, unless you explicitly turn that off (but then you probably should have used ArrayPlot[] to begin with). Sep 22 '17 at 12:11

Let us denote your colour function by cf. Then MatrixPlot will use cf[0.5] for zero, colour function values in the range 0.5-1.0 for positive elements and values in the range 0.0-0.5 for negative elements.

This means that out of the built-in colour functions, those are most suitable for use with MatrixPlot which are symmetric to the middle, e.g. GreenPinkTones, MintColors, ThermometerColors, RedGreenSplit, LightTemperatureMap, TemperatureMap, etc.

If you create your own colour function, make it like this too. For example:

ColorFunction -> (Blend[{Blue, White, Red}, #] &)


@J.M. took a different approach: he set ColorFunctionScaling -> False, which asks MatrixPlot to pass the matrix values to the colour function without any scaling.

Example:

cfun = Blend[{Blue, White, Red}, #] &;

n = 200;
MatrixPlot[
SparseArray[RandomInteger[{1, 20}, {n, 2}] -> RandomReal[{-1, 2}, n]],
ColorFunction -> cfun
] This is the colour function:

LinearGradientImage[cfun, {360, 36}] • thanks a lot! I voted @J.M.'s answer up and yours as well - they both answer the question, I think. Yours explains very well how the Mathematica schemes function and help understanding how to makes one's own
– MXJ
Sep 20 '17 at 16:50