16
$\begingroup$

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]

enter image description here

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

4 Answers 4

12
$\begingroup$
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]

enter image description here

$\endgroup$
4
  • $\begingroup$ Oops, looks like J.M. beat me to it. $\endgroup$
    – Cassini
    Commented Jan 30, 2012 at 3:34
  • $\begingroup$ 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. $\endgroup$
    – rcollyer
    Commented Jan 30, 2012 at 3:37
  • 3
    $\begingroup$ He left a comment, not an answer. Yours wins by default. $\endgroup$
    – rcollyer
    Commented Jan 30, 2012 at 3:38
  • 1
    $\begingroup$ Indeed, @rcollyer's right. ;) $\endgroup$ Commented Jan 30, 2012 at 3:42
10
$\begingroup$

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.

$\endgroup$
5
  • $\begingroup$ How did you know about ChartElementDataFunction. I couldn't find it in documentation. $\endgroup$ Commented Jan 30, 2012 at 6:32
  • $\begingroup$ @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. $\endgroup$ Commented Jan 30, 2012 at 6:49
  • $\begingroup$ 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 $\endgroup$ Commented Jan 30, 2012 at 7:00
  • $\begingroup$ @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. $\endgroup$ Commented Jan 30, 2012 at 7:26
  • $\begingroup$ Just to qualify the comment at the start of this thread. I typed ?ChartElementDataFunction and this failed to return a description. $\endgroup$ Commented Jan 30, 2012 at 8:13
9
$\begingroup$

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

$\endgroup$
8
$\begingroup$

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]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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