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.

This question is a follow up from this one. I want to be able to specify a list of colours for my bars in BarChart. In responses to the question I linked to, @kguler produced the following, which sets the bars to the left of x=8 as a different colour:

cedF[{{xmin_, xmax_}, {ymin_, ymax_}}, ___] :={If[xmax <= 8, 
   RGBColor[1, 0, 0], Sequence[]],
  Dynamic@EdgeForm[Directive[Thickness[.015], Lighter@CurrentValue["Color"]]],
 Rectangle[{xmin, ymin}, {xmax, ymax}, RoundingRadius -> 5]};

Histogram[RandomVariate[NormalDistribution[10, 2], 500],ChartStyle -> "Pastel", 
  ChartElementFunction -> cedF]

kguler example

My question is how to generalise this: I would like to be able to have a list that specifies the colours of every bin uniquely. How would I go about this? If[] statements seem a bit clunky for this application.

share|improve this question
    
You might take a look at Which[] and Switch[]. –  VLC Oct 11 '12 at 9:36
    
...or Piecewise[]. Look at ChartStyle as well. –  J. M. Oct 11 '12 at 9:44
    
Thanks @J.M. and VLC, that's helpful. It's silly how all my problems involve not knowing the fundamental functions, but I guess that's life for a Mathematica newbie. –  Ooku Oct 11 '12 at 9:47
    
@Ooku: there's a lot to gain from browsing the docs. In particular, whenever you want to know if something can be done with a function, look at the doc pages for the function itself, as well as the options that seem relevant to what you want to do. Since you're dealing with BarChart[], you could have looked at the options that contained the words Chart or Style in them... –  J. M. Oct 11 '12 at 9:50
    
Yes, that's clear now. I was looking for a complicated solution when there was a simple one right under my nose! So I guess my question was not only "RTFM", but "XY" also :/ –  Ooku Oct 11 '12 at 9:55

1 Answer 1

up vote 7 down vote accepted

Here is a modification of the custom function cedf2 that accepts a list of {from,to,color} triples:

ClearAll[cedf3];
cedf3[args : {{_, _, _} ..}, dfltClr_: Red,thcknss_: Small,rndngrds_: 0][{{xmin_, xmax_}, {ymin_, ymax_}}, ___] :=
 With[{clr = Function[{lst, xxx},
    With[{pick = Pick[lst, #[[1]] < xxx <= #[[2]] & /@ lst]}, 
     If[pick == {}, dfltClr, Last @@ pick]]][args, xmax]}, {clr, 
 Dynamic@EdgeForm[Directive[Thickness[thcknss], Lighter@CurrentValue["Color"]]], 
 Rectangle[{xmin, ymin}, {xmax, ymax}, RoundingRadius -> rndngrds]}]

(I am sure there is better/shorter way using Which, Switch, Piecewise to pick the bin color instead of the clunky one above using Pick)

Update: A cleaner version using Piecewise:

ClearAll[cedf4];
cedf4[args : {{_, _, _} ..}, dfltClr_:Red,thcknss_:Small, rndngrds_: 3][{{xmin_, xmax_}, {ymin_, ymax_}}, ___] :=
{Piecewise[Map[{#[[3]], #[[1]] < xmax <= #[[2]]} &, args], dfltClr],
 Dynamic@EdgeForm[Directive[Thickness[thcknss], Lighter@CurrentValue["Color"]]],
 Rectangle[{xmin, ymin}, {xmax, ymax}, RoundingRadius -> rndngrds]}

Usage: some input data:

 binsAndColors1 = Transpose@{Most@Range[0, 50], Rest@Range[0, 50], 
     ColorData["Atoms", "ColorList"][[;; 50]]};
 binsAndColors2 = Transpose@{Most@Range[0, 50, 2], Rest@Range[0, 50, 2], 
     ColorData["Crayola", "ColorList"][[;; 25]]}

Histogram[RandomVariate[NormalDistribution[10, 2], 500], 
  ChartElementFunction -> (cedf3[binsAndColors1, Red, Medium, 3])]

enter image description here

Color consecutive bars with the same color:

Histogram[RandomVariate[NormalDistribution[10, 2], 500], 
  ChartElementFunction -> (cedf3[binsAndColors2, Red,Medium, 3])]

enter image description here

Alternatively, you can use ChartStyle:

 Histogram[RandomVariate[NormalDistribution[0, 1], 500], 
   ChartStyle -> {ColorData["Crayola", "ColorList"][[;; 70]]}]

enter image description here

or, to color neighboring bins with the same color:

Histogram[RandomVariate[NormalDistribution[0, 1], 500], 
 ChartStyle -> {Riffle[ColorData["Crayola", "ColorList"][[;; 70]], 
    ColorData["Crayola", "ColorList"][[;; 70]]]}]

enter image description here

share|improve this answer

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.