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.

  • $\begingroup$ You might take a look at Which[] and Switch[]. $\endgroup$
    – VLC
    Oct 11, 2012 at 9:36
  • $\begingroup$ ...or Piecewise[]. Look at ChartStyle as well. $\endgroup$ Oct 11, 2012 at 9:44
  • $\begingroup$ 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. $\endgroup$
    – Ooku
    Oct 11, 2012 at 9:47
  • $\begingroup$ @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... $\endgroup$ Oct 11, 2012 at 9:50
  • $\begingroup$ 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 :/ $\endgroup$
    – Ooku
    Oct 11, 2012 at 9:55

1 Answer 1


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

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:

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


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.