I'm not sure what the best way to uploadUpdate I've created a package ispackage, so I will paste the contents belowand uploaded it on on github. I have the following text in a file called "DivergentColorMaps Much thanks to J.m" located in a folder named "DivergentColorMaps"M., located whereI've changed a few functions around to make them simpler - but I keep my packageshave kept all the color conversion functions because I like them for clarity, and they don't slow it down compared to the built-in ColorConvert
function.
BeginPackage["DivergentColorMaps`"]
divergentColorFuncDivergentColorFunc::usage = "divergentColorFunc["DivergentColorFunc[{r1,g1,b1},{r2,b2,g2}] returns a continuously diverging color map which interpolates between two RGB colors.\n
divergentColorFunc[color1DivergentColorFunc[color1, color2] takes two color objecst as input and returns a continuously diverging color map."
cool2warmCoolToWarm::usage = "cool2warm[n]"Cool2Warm[n] gives the cool to warm color map, with n taking values between 0 and 1"
divergentColorSchemeDivergentColorScheme::usage = "divergentColorScheme[scheme]"DivergentColorScheme[scheme] gives a diverging color map which interpolates between the starting and ending colors in a builtin scheme"
divergentMapsDivergentMaps::usage = "A"DivergentMaps is list of four divergent color maps used in http://www.kennethmoreland.com/color-maps/ColorMapsExpanded.pdf . divergentMaps[[1]] is equivalent to cool2warm"Cool2Warm"
Begin["`Private`"]
(*
The reference white values and transformation matrix correspond to the
fact that in Mathematica, the RGB white point uses the D65 standard,
while the XYZ and LAB color spaces use the D50 white point. This is
different than in Moreland's paper or other color conversion websites
*)
referenceWhite = {96.42, 100.0, 82.49};
transformation = {{0.436075, 0.385065, 0.14308},
{0.222504, 0.716879, 0.0606169},
{0.0139322, 0.0971045, 0.714173}};
(*Forward Transformations*)
rgb2xyz[r_, g_, b_] := Module[
{transm, rl, gl, bl},
{rl, gl, bl} = If[# > .04045,
((# + 0.055)/1.055)^2.4,
#/12.92] & /@ {r, g, b};
transm = transformation;
100 transm.{rl, gl, bl}
];
xyz2lab[xi_, yi_, zi_] := Module[{f, refx, refy, refz, x, y, z},
{refx, refy, refz} = referenceWhite;
f = If[((#) > 0.008856),
(#^(1/3)),
(7.787 # + 4/29.)] &;
{x, y, z} = f /@ ({xi, yi, zi}/{refx, refy, refz});
{116.0 (y - 4./29), 500.0 (x - y), 200 (y - z)}
];
lab2msh[l_, a_, b_] := Module[{Sqrt[l^2m += a^2Norm[{l, +a, b^2]b}]}, {m,
If[m==0, 0, ArcCos[l/Sqrt[l^2 +m]], a^2Arg[a + b^2]], ArcTan[a,b b]I]};];
rgb2msh[r_, g_, b_] := lab2msh @@ xyz2lab @@ rgb2xyz @@ {r, g, b};
(* Backward Transformations *)
msh2lab[m_, s_, h_] := {m Cos[s], m Sin[s] Cos[h], m Sin[s] Sin[h]};
lab2xyz[l_, a_, b_] := Module[{x, y, z, refx, refy, refz},
{refx, refy, refz} = referenceWhite;
y = (l + 16)/116.;
x = a/500. + y;
z = y - b/200.;
{x, y, z} =
If[#^3 > 0.008856, #^3, (# - 4./29)/7.787] & /@ {x, y, z};
{x, y, z} {refx, refy, refz}
];
xyz2rgb[x_, y_, z_] := Module[{transm, r, g, b},
transm = Inverse@transformation;
{r, g, b} = {x, y, z}/100;
{r, g, b} = transm.{r, g, b};
If[# > 0.0031308, 1.055 #^(1/2.4) - 0.055, 12.92 #] & /@ {r, g, b}
];
msh2rgb[m_, s_, h_] := xyz2rgb @@ lab2xyz @@ msh2lab @@ {m, s, h};
adjusthue[msat_, ssat_, hsat_, munsat_] := Module[{hspin},
If[msat >= munsat,
hsat,
hspin = ssat Sqrt[munsat^2 - msat^2]/(msat Sin[ssat]);
If[hsat > -\[Pi]/3,
hsat + hspin,
hsat - hspin
]
]
];
interpolatecolor[{r1_, g1_, b1_}, {r2_,
g2_
interpolatecolor[rgb1_List, b2_}rgb2_List, interp_]interp_?NumericQ] :=
Module[
{m1, s1, h1, m2, s2, h2, interpvar, mmid, smid, hmid},
(*If points are saturated and distinct,
place white in the middle *)
{m1, s1, h1} =
rgb2msh @@ {r1, g1, b1};rgb1;
{m2, s2, h2} = rgb2msh @@ {r2, g2, b2};rgb2;
interpvar = interp;
If[s1 > 0.05 && s2 > 0.05 && Abs[h1 - h2] > Pi/3,
mmid = Max@{m1, m2, 88.};
If[interp < 1/2,
{m2, s2, h2, interpvar} = {mmid, 0, 0, 2 interp};,
{m1, s1, h1, interpvar} = {mmid, 0, 0, 2 interp - 1};
];
];
(* Adjust hue of unsaturated colors *)
Which[s1 < 0.05 && s2 > 0.05,
h1 = adjusthue[m2, s2, h2, m1];,
s2 < 0.05 && s1 > 0.05,
h2 = adjusthue[m1, s1, h1, m2];
];
{mmid, smid, hmid} = (1 - interpvar) {m1, s1, h1} +
interpvar {m2, s2, h2};
msh2rgb @@ {mmid, smid, hmid}
];
divergentcolorfunc[rgb1_DivergentColorFunc[rgb1_, rgb2_] :=
With[{interp = RGBColor @@@@@ Chop @ (interpolatecolor[rgb1, rgb2, #] &;&/@ Range[0,1,.05])},
Blend[interp, #] & ];
divergentColorFunc[rgb1_List, rgb2_List] :=
Module[{colorlist, color1, color2},(*If either color is pure black,
we run into division by zero errors*)
color1 =
If[SameQ[N@rgb1, {0., 0., 0.}], {0.001, 0.001, 0.001}, rgb1];
color2 =
If[SameQ[N@rgb2, {0., 0., 0.}], {0.001, 0.001, 0.001}, rgb2];
colorlist =
interpolatecolor[color1, color2, #] & /@ Range[0, 1, .05];
Evaluate[Blend[RGBColor @@@ colorlist, #] &]];
divergentColorFunc[col1_DivergentColorFunc[col1_?ColorQ, col2_?ColorQ] := divergentColorFuncDivergentColorFunc @@ List @@@ (ColorConvert[#, RGBColor]&/@ ColorConvert[{col1, col2}, RGBColor]) ;
cool2warmDivergentColorScheme[scheme_String] := divergentColorFunc[{59.,
76., 192}DivergentColorFunc @@ ColorData[scheme] /255.,@ {180., 4.0, 38.1}/255.];;
divergentColorScheme[scheme_String] :=
divergentColorFunc @@
CoolToWarm List= @@@DivergentColorFunc[{0.23, ColorData[scheme]0.299, /@0.754}, {0.706, 0.016, 10.150};];
divergentMapsDivergentMaps =
divergentColorFunc[#1DivergentColorFunc[#1, #2] & @@@ {{{0.23, 0.299, 0.754}, {0.706,
0.016, 0.150}},
{{0.436, 0.308, 0.631}, {0.759, 0.334, 0.046}}, {{0.085, 0.532,
0.201}, {0.436, 0.308, 0.631}}, {{0.217, 0.525, 0.910}, {0.677,
0.492, 0.093}}, {{0.085, 0.532, 0.201}, {0.758, 0.214, 0.233}}};
End[]
EndPackage[]
newcolorfunc = divergentColorFunc[DivergentColorFunc[{0, 0, .5}, {.5, 0, 0}]
(* Blend[
Apply[RGBColor,
DivergentColorMaps`Private`colorlist$1593, {1}], #1] &0}] *)];
showcolorfunction@newcolorfunc
newcolorfunc2 =
divergentColorFunc[Darker[XYZColor[1DivergentColorFunc[Darker[XYZColor[1, 0.2, 1]],
LUVColor[.16, .5, 1]];
showcolorfunction@newcolorfunc2
showcolorfunction@cool2warmshowcolorfunction@CoolToWarm
showcolorfunction /@ divergentMaps[[2DivergentMaps[[2 ;;]]
showcolorfunction /@ (divergentColorSchemeDivergentColorScheme /@ {"RoseColors", "AvocadoColors"})