# ColorFunction in Histogram[]

Let's say I have a Histogram:

Histogram[RandomVariate[NormalDistribution[10, 2], 500]]


and I want the bars positioned to the left of 8 on the horizontal axis to be a different colour.

The Mathematica documentation shows how to do this for the height of bars, but not for their position:

Histogram[RandomVariate[NormalDistribution[10, 2], 500],
ColorFunction -> (Which[# < 40, Yellow, 40 <= # < 90, Red, True, Blue] &),
ColorFunctionScaling -> False]


How do I call the positions of the bars from Histogram and put them into my ColorFunction?

-
You will probably need to get the bin data with HistogramList and plot it with BarChart -- I don't have HistogramList in v7 or I'd make this an answer. – Mr.Wizard Oct 6 '12 at 10:12

You can use a custom ChartElementDataFunction as follows:

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]


EDIT: Adding arguments to cedf:

cedf2[from_,to_,color_: Red,thickness_:Small,rndngradius_: 0][{{xmin_, xmax_}, {ymin_, ymax_}}, ___] :=
{If[from < xmax <= to, color, Sequence[]],
Dynamic@EdgeForm[Directive[Thickness[thickness], Lighter@CurrentValue["Color"]]],

Histogram[RandomVariate[NormalDistribution[10, 2], 500], ChartStyle -> "Pastel",
ChartElementFunction -> cedf2[6, 10, Purple, Small, 3]]


Alternatively, you can build a custom data function using the built-in ChartElementDataFunctions:

sgmntsclF = ChartElementDataFunction["SegmentScaleRectangle",
"Segments" -> 8, "ColorScheme" -> "TemperatureMap"];
"ColorScheme" -> "Rainbow", "GradientOrigin" -> Top];

Histogram[RandomVariate[NormalDistribution[10, 2], 500], ChartStyle -> "Pastel",
ChartElementFunction -> ((If[7 < {##}[[1]][[1, 2]] <= 10,
sgmntsclF[##], grdntrctF[##]]) &)]


-
I didn't think of this approach. Slick! – Mr.Wizard Oct 6 '12 at 15:53
Thank you, @Mr.W. – kglr Oct 6 '12 at 19:53
Great. If I wanted to generalise this, how would I go about doing it? i.e. instead of just specifying that bins to the left of X should be red, what about a list specifying a separate colour for each bin? – Ooku Oct 11 '12 at 8:26
Ooku, the simplest way would be using ChartStyle->{{color1,color2,...}} which colors each bar with the corresponding color in the list. If the list of colors is shorter than the number of bins, it cycles through the colors. For example: Histogram[RandomVariate[NormalDistribution[0, 1], 500], ChartStyle -> {ColorData["Atoms", "ColorList"][[;; 70]]}]. If you need a more general version of cedf2 that accepts a list of triples {{from1,to1,color1},{from2,to2,color2}...} I will update with an example of how it can be done. – kglr Oct 11 '12 at 10:16

You will probably need to get the bin data with HistogramList and plot it with BarChart.

I don't have HistogramList in v7, but here is a basic proof of concept:

hist = Histogram[RandomReal[NormalDistribution[10, 2], 500]]

Cases[hist, RectangleBox[{a_, _}, {b_, x_}] :> {b, x}, -1];

If[# <= 8, Style[#2, Red], #2] & @@@ %;

BarChart @ %


I'm flying blind here as I can't test this, but maybe it works:

dat = HistogramList[RandomVariate[NormalDistribution[10, 2], 500]];

If[# <= 8, Style[#2, Red], #2] & @@@ Transpose @ dat;

BarChart @ %

-
The Cases[] bit doesn't work for me (v8), can you explain what the -1 at the end is doing? – Ooku Oct 6 '12 at 10:31
@Ooku I was afraid there was too much change between versions. :-/ -1 in Cases just specifies searching for the pattern all the way to the bottom level. Apparently RectangleBox is either no longer used, or used with a different syntax. Cases should return a list of the right $x$ coordinate and top $y$ coordinate for each bar, e.g. {{3, 1}, {5, 4}, {6, 7}, {7, 24}, {8, 47}, {9, 86}, {10, 95}, {11, 94}, {12, 71}, {13, 37}, {14, 25}, {15, 6}, {16, 3}} – Mr.Wizard Oct 6 '12 at 10:38
@Ooku I think this would be similar to HistogramList[ . . . ] // Transpose -- please try that. – Mr.Wizard Oct 6 '12 at 10:40
@Ooku I added some code for you to try. – Mr.Wizard Oct 6 '12 at 10:42