# Colours in BarChart[]

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]


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.

-
You might take a look at Which[] and Switch[]. –  VLC Oct 11 '12 at 9:36
...or Piecewise[]. Look at ChartStyle as well. –  Ｊ. Ｍ. 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... –  Ｊ. Ｍ. 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

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


Color consecutive bars with the same color:

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


Alternatively, you can use ChartStyle:

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


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


-