# How can I create a ColorFunction using Blend?

As shown below, I am trying to find a cool way to show some variance weighted deviation from the mean. There are 10 attributes that I compute the distance for.

How can I add a color function such that it is progressively a darker shade of red when its value is negative (towards the left) and green when the value is positive (towards the right of the graphics)?

distance = {0.245, -0.235, 0.053, -0.048, -0.128,
-0.007, -0.075, -0.067,-0.005, 0.082}

Show[
Function[
attributes,
Graphics[
Rectangle[
{If[distance[[attributes]] < 0, distance[[attributes]]*10, 0],
attributes - 1},
{If[distance[[attributes]] < 0, 0, distance[[attributes]]*10],
attributes}
],
PlotRange -> {{-5, 5}, {0, 10}},
Epilog -> {White, Line[{{0, 0}, {0, 11}}]}
]] /@ Range[10],
Frame -> True]


• Something like Blend[{Darker[Red], Lighter[Green]}, #] &? Commented Jan 30, 2012 at 3:27

distance = {0.245, -0.235, 0.053, -0.048, -0.128, -0.007, -0.075, -0.067, -0.005, 0.082}

Show[Function[attributes,
Graphics[{Blend[{{-Max[Abs[distance]], Red}, {0, LightRed}, {0,
LightGreen}, {+Max[Abs[distance]], Green}},
distance[[attributes]]],
Rectangle[{If[distance[[attributes]] < 0,
distance[[attributes]]*10, 0],
attributes - 1}, {If[distance[[attributes]] < 0, 0,
distance[[attributes]]*10], attributes}],
PlotRange -> {{-5, 5}, {0, 10}}},
Epilog -> {White, Line[{{0, 0}, {0, 11}}]}]] /@ Range[10],
Frame -> True]


• Oops, looks like J.M. beat me to it. Commented Jan 30, 2012 at 3:34
• I formatted your code. It is straightforward to do so, yourself: just indent the code by 4-spaces, or select the code and type ctrl+k. Commented Jan 30, 2012 at 3:37
• He left a comment, not an answer. Yours wins by default. Commented Jan 30, 2012 at 3:38
• Indeed, @rcollyer's right. ;) Commented Jan 30, 2012 at 3:42

We can achieve such visual style with built-in tools, applying some color gradient along the rectangles. Using your data:

distance = {0.245, -0.235, 0.053, -0.048, -0.128,
-0.007, -0.075, -0.067,-0.005, 0.082}


BarChart will do the job:

BarChart[distance, ChartElementFunction -> ChartElementDataFunction[
"GradientScaleRectangle", "ColorScheme"-> "DarkRainbow"], BarOrigin ->Left,
AspectRatio ->1, Frame ->True, GridLines -> {Range[-.22, .24, .02], Automatic}]


The horizontal scale is a bit different than yours, but you can easily adjust it. I personally enjoy very much that just a few lines will do things like:

BarChart[RandomReal[{-1, 1}, {50, 50}], ChartLayout -> "Stacked", Axes -> None,
BarSpacing ->{0, 0}, PerformanceGoal ->"Speed", ChartStyle -> "AvocadoColors"]


That was a Documentation example.

• How did you know about ChartElementDataFunction. I couldn't find it in documentation. Commented Jan 30, 2012 at 6:32
• @MikeHoneychurch I now added a link to words "built-in tools" in the first line of the post to refer to the corresponding Documentation example. Commented Jan 30, 2012 at 6:49
• Interesting that it turned up there but is not documented at ref/ChartElementFunction and doesn't seem to have its own documentation page explaining usage Commented Jan 30, 2012 at 7:00
• @MikeHoneychurch If you search Documentation for ChartElementDataFunction - there will be many links. Because functions such as SectorChart3D have a special section in Documentation under Options dedicated to the usage of ChartElementDataFunction. But you're right - currently no separate article. Commented Jan 30, 2012 at 7:26
• Just to qualify the comment at the start of this thread. I typed ?ChartElementDataFunction and this failed to return a description. Commented Jan 30, 2012 at 8:13

Looking at David's answer, it seems to me that you might want to

1. explicitly target the maximum and minimum values in your dataset to be pure green and red, respectively; and
2. have a neutral color, like gray, as the color at 0, so as to avoid the brownish colors in the middle.

To that end, I used this for the color:

If[distance[[attributes]] < 0,
Blend[{{Min[distance], Red}, {0, Gray}}, distance[[attributes]]],
Blend[{{Max[distance], Green}, {0, Gray}}, distance[[attributes]]]]


If you want red on the negative side and green on the positive side without having a transition from red to green, you could do something like

colorf = Blend[{Darker[Red, .7 #/Min[distance]],
Darker[Green, .7 #/Max[distance]]}, UnitStep[#]] & ;

BarChart[distance,
ColorFunction -> colorf,
ColorFunctionScaling -> False,
BarOrigin -> Left, Frame -> True, BarSpacing -> None]