Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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}

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

enter image description here

share|improve this question
Something like Blend[{Darker[Red], Lighter[Green]}, #] &? – J. M. Jan 30 '12 at 3:27
up vote 11 down vote accepted
distance = {0.245, -0.235, 0.053, -0.048, -0.128, -0.007, -0.075, -0.067, -0.005, 0.082}

   Graphics[{Blend[{{-Max[Abs[distance]], Red}, {0, LightRed}, {0, 
        LightGreen}, {+Max[Abs[distance]], Green}}, 
     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]

enter image description here

share|improve this answer
Oops, looks like J.M. beat me to it. – Cassini Jan 30 '12 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. – rcollyer Jan 30 '12 at 3:37
He left a comment, not an answer. Yours wins by default. – rcollyer Jan 30 '12 at 3:38
Indeed, @rcollyer's right. ;) – J. M. Jan 30 '12 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}]

enter image description here

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

enter image description here

That was a Documentation example.

share|improve this answer
How did you know about ChartElementDataFunction. I couldn't find it in documentation. – Mike Honeychurch Jan 30 '12 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. – Vitaliy Kaurov Jan 30 '12 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 – Mike Honeychurch Jan 30 '12 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. – Vitaliy Kaurov Jan 30 '12 at 7:26
Just to qualify the comment at the start of this thread. I typed ?ChartElementDataFunction and this failed to return a description. – Mike Honeychurch Jan 30 '12 at 8:13

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[#]] & ;

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

Mathematica graphics

share|improve this answer

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

Mathematica graphics

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.