Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Consider the following:

fakedata = RandomReal[{4, 9}, {5, 10}];
BarChart[fakedata, BarSpacing -> {0, 0.4}, 
 ChartBaseStyle -> EdgeForm[], 
 ChartStyle -> {{Magenta, Blue, Red, Orange, Green}, Opacity[#] & /@ Range[0.1, 1, 0.1]}]

enter image description here

This is all well and good, but what I really want is the following, but grouped, so that the bars are opaque, the ticks come out how I want them, and the little space in between the groups (from the BarSpacing option) shows up:

BarChart[Flatten@fakedata, BarSpacing -> {0, 0.4}, 
 ChartBaseStyle -> EdgeForm[], 
 ChartStyle -> 
  Flatten@Outer[Blend[{{0, White}, {0.7, #1}, {1.1, Black}}, #2] &, {Magenta, 
     Blue, Red, Orange, Green}, Range[0.1, 1, 0.1]]]

enter image description here

Unfortunately if I create a "matrix" of colours as the value of the ChartStyle option, only the second list is picked up, and I get this:

BarChart[fakedata, BarSpacing -> {0, 0.4}, 
 ChartBaseStyle -> EdgeForm[], 
 ChartStyle -> Outer[Blend[{{0, White}, {0.7, #1}, {1.1, Black}}, #2] &, {Magenta, 
    Blue, Red, Orange, Green}, Range[0.1, 1, 0.1]]]

enter image description here

How can I style my bars individually like in the second example, when the data are grouped?

share|improve this question
add comment

1 Answer

up vote 8 down vote accepted
+100
 fakedata = RandomReal[{4, 9}, {5, 10}];
 styles = Outer[Blend[{{0, White}, {0.7, #1}, {1.1, Black}}, #2] &, {Magenta, Blue,
 Red, Orange, Green}, Range[0.1, 1, 0.1]];
 BarChart[MapThread[Style, {fakedata, styles}, 2] (*thanks: Verbeia & Mr.Wizard *),
 BarSpacing -> {0, 0.4}, ChartBaseStyle -> EdgeForm[]]

enter image description here

Alternatively, one replace MapThread[...] by :

 Partition[Inner[Style, Flatten@fakedata, Flatten@styles, List], 10] (* thanks: VLC *)
 (* or *)
 ArrayReshape[Inner[Style, Flatten@fakedata, Flatten@styles, List], {5, 10}] (* Version  9 *)

Update: Using ChartElementFunction

 cedFX[{{xmin_, xmax_}, {ymin_, ymax_}}, ___] := {Dynamic@
   Blend[{{0, White}, {0.7, CurrentValue["Color"]}, {1.1, Black}}, 
   ((1/10) Mod[xmin - .4 Quotient[xmin, 10], 10])],
   Rectangle[{xmin, ymin}, {xmax, ymax}]}; 
  BarChart[fakedata, BarSpacing -> {0, 0.4}, ChartBaseStyle -> EdgeForm[],
  ChartElementFunction -> cedFX,
  ChartStyle -> {{Magenta, Blue, Red, Orange, Green}, None}]

enter image description here

(Note: needs better tuning of the blending parameter as a function of xmin,xmax and the value of the BarSpacing option)

share|improve this answer
    
For those that do not have Mathematica 9 and thus no ArrayShape function: BarChart[Partition[ Inner[Style, Flatten@fakedata, Flatten@styles, List], 10], BarSpacing -> {0, 0.4}, ChartBaseStyle -> EdgeForm[]] –  VLC Feb 12 '13 at 10:19
    
@VLC, thank you, good point; will update. –  kguler Feb 12 '13 at 10:30
    
Thanks kguler, had completely forgotten that you can style individual bars like that. –  Verbeia Feb 12 '13 at 10:59
    
@Verbeia, my pleasure. Good question; it is puzzling that it cannot be done using ChartStyle. –  kguler Feb 12 '13 at 11:15
    
Equivalent way to get the colors: MapThread[ Style[#1, #2] &, {fakedata52, Outer[Blend[{{0, White}, {0.7, #1}, {1.1, Black}}, #2] &, {Magenta, Blue, Red, Orange, Green}, Range[0.1, 1, 0.1]]}, 2]. It's worth pointing out that if you have a custom function that uses the data anywhere (e.g. calculated the Max and Min to work out ticks, you can't just pass the Styled data to the function. You'd need to create a SpecialStyles type option to that function, and combine the styles and data together in the charting function. –  Verbeia Feb 12 '13 at 22:24
show 6 more comments

Your Answer

 
discard

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.