Group Abstract Group Abstract

Message Boards Message Boards

Blending color gradients to expand color schemes available for plotting

GROUPS:
When plotting analytic expressions with such functions like Plot3D, ContourPlot, etc. we most commonly use color gradients to beautify the graphs. Here are examples for "SouthwestColors" and "Rainbow" gradient color schemes:
{ReliefPlot[Table[RandomReal[] (Sin[x + y^2] + Sin[x^2 + 3 y]), {x, -3, 3, .01}, {y, -3, 3, .01}],
  ColorFunction -> ColorData["SouthwestColors"]],

ReliefPlot[Table[Evaluate[Sum[Sin[RandomReal[4, 2].{x, y}], {5}]], {x, 0, 10, .05}, {y, 0, 10, .05}],
  ColorFunction -> ColorData["Rainbow"]]}



There are 51 built in gradients in Mathemtica.



We could have at least 51^2 if we would learn how to blend them. Define a blending function 
mixer[grad1_, grad2_][m_, x_] := Blend[{ColorData[grad1][x], ColorData[grad2][x]}, m]

where m is the blending ratio. Now we can mix randomly color gradients at 0.5 even blending ratio to see what kind of colors palettes we get:
g[grad1_, grad2_] := ContourPlot[y + Sin[x^2 + 3 y], {x, -3, 3}, {y, -3, 3},
  ColorFunction -> (mixer[grad1, grad2][.5, #] &), Frame -> False,
  PlotRangePadding -> 0, PlotLabel -> Style[grad1 <> "-" <> grad2, 10]]

GraphicsGrid[Partition[ParallelTable[g[RandomChoice[ColorData["Gradients"]],
RandomChoice[ColorData["Gradients"]]], {25}], 5], Spacings -> 0, ImageSize -> 800]



We could also blend at a changing ration, so that at min we have one color gradient and at max the other one, with smooth change in between.

f[grad1_, grad2_] := DensityPlot[Sin[x] Sin[y], {x, -Pi, Pi}, {y, -Pi, Pi},
  ColorFunction -> (mixer[grad1, grad2][#, #] &), Frame -> False,
  PlotRangePadding -> 0, PlotLabel -> Style[grad1 <> "-" <> grad2, 10], PlotPoints -> 40]

GraphicsGrid[Partition[ParallelTable[f[RandomChoice[Complement[ColorData["Gradients"], {"BrightBands", "DarkBands"}]],
    RandomChoice[Complement[ColorData["Gradients"], {"BrightBands", "DarkBands"}]]], {25}], 5], Spacings -> 0, ImageSize -> 800]




A Manipulate to play with blending:
 Manipulate[
  GraphicsGrid[{
    {DensityPlot[x, {x, 0, 1}, {y, 0, .1}, ColorFunction -> gradients1, AspectRatio -> Automatic, Frame -> False]},
    {DensityPlot[x, {x, 0, 1}, {y, 0, .1}, ColorFunction -> (mixer[gradients1, gradients2][m, #] &),
         AspectRatio -> Automatic, Frame -> False]},
    {DensityPlot[x, {x, 0, 1}, {y, 0, .1}, ColorFunction -> gradients2, AspectRatio -> Automatic, Frame -> False]}
    }]
  , {{m, .5, "blend"}, 0, 1, Appearance -> "Labeled"}
  , {{gradients1, "SandyTerrain", "1st palette"}, (# -> Show[ColorData[#, "Image"], ImageSize -> 100]) & /@ ColorData["Gradients"]}
, {{gradients2, "Rainbow", "2nd palette"}, (# -> Show[ColorData[#, "Image"], ImageSize -> 100]) & /@ ColorData["Gradients"]}]



I think these are pretty nice subtle color palettes. Now I have two questions.
  • How do we make the mixer function faster, efficient?
  • How do we do the same for "Indexed" discrete color data ColorData["Indexed"] ?
POSTED BY: Vitaliy Kaurov
Answer
1 year ago
Interesting idea, but mixing color schemes leads to 'duller' colors generally, so they work less good compared to the originals I think.

I'm not sure, but it might be faster to directly use Blend instead of ColorData:
ColorData["Rainbow"][x]
=>
Blend["Rainbow", x]
ColorData eventually calles Blend I think, maybe skipping this extra step saves a little time.

Regards!
POSTED BY: Sander Huisman
Answer
1 year ago
Thank you, Sander, interesting observation, - Blend seems to be about 3 times faster than ColorData. I personally like subtle palettes, but mostly for artistic applications. For more contrast mixing of palettes blending ratio should be used as a function too like in the 2nd example I gave.
POSTED BY: Vitaliy Kaurov
Answer
1 year ago
Cool idea Vitaliy! It's always great to expand the artistic capabilities of Mathematica.

Thank you, Sander, for pointing this out. It's great having you in Community. I first heard about your mathematical pasta in 2012 "Pasta Graduates From Alphabet Soup to Advanced Geometry". It would be great if you could share in Community some of these great ideas you got for modeling different types of pasta using Mathematica emoticon

Answer
1 year ago
@Vitaliy
Glad to hear it is faster. I found out using some spelunking that Blend is used when you ask for a color using ColorData. Interesting that it is 3x faster!! Didn't expect that at all.

@Bernat
Nice to hear I have some fans ;) I changed my website completely a month or two ago, I didn't post enough to keep it 'active'. Maybe I will post all my pasta's at some point. I'll let you know emoticon
You got a nice website by the way...
POSTED BY: Sander Huisman
Answer
1 year ago


As Vitaliy proposed, mixing the colorfunction of Mathematica. Basically this is a table, vertically and horizontally the different colorschemes. Then each sub-block is a blend from one colorfunction to the other. (vertically is the 'blend' for each colorfunction, horizontally is the blend between colorfunctions). 

Here is the code: (note that it is pretty CPU intensive, it will take 10 minutes on a fast machine!)
 ClearAll[ColorBlendData]
 ColorBlendData[colf1_,colf2_,n_Integer]:=Module[{data},
 data=Array[Blend[{Blend[colf1,#1],Blend[colf2,#1]},#2]&,{n,n},{{0,1},{0,1}}];
 Apply[List,data,{2}]
 ]
 n=20;
 b=2;
 colfs=ColorData["Gradients"];
 CloseKernels[];
LaunchKernels[4];
DistributeDefinitions[n,b,colfs,ColorBlendData];
AbsoluteTiming[data=ParallelTable[ColorBlendData[f,g,n],{f,colfs},{g,colfs}];]
data=Flatten[data,{{1,3},{2,4}}];

headerdata=Table[ColorBlendData[f,f,n],{f,colfs}];
headerdatatop=Flatten[Transpose/@headerdata,1]\[Transpose]//Image;
headerdataside=Flatten[headerdata,1]//Image;
topcorner=ConstantArray[{1,1,1},{n,n}]//Image;
img=Image[data];

img=ImagePad[img,2,White];
headerdatatop=ImagePad[headerdatatop,2,White];
headerdataside=ImagePad[headerdataside,2,White];
topcorner=ImagePad[topcorner,2,White];

bottom=ImageAssemble[{headerdataside,img}];
top=ImageAssemble[{topcorner,headerdatatop}];

img=ImageAssemble[{{top},{bottom}}]
(*Export["colorfields.png",img]*)
POSTED BY: Sander Huisman
Answer
1 year ago
Sander, this is great! Thank you for investing yours and your computer time into it ;-)
POSTED BY: Vitaliy Kaurov
Answer
1 year ago