# Finding where maximum of histogram occurs

If I have made a histogram of some data. How can I find out at which x-bin position the maximum occurs?

SeedRandom[2];
data = RandomReal[1000, {1000}];
Histogram[data, {20}, Frame -> True, FrameLabel -> {"x", "count"}]


• Use HistogramList. – JimB Jan 25 at 17:03
• Use HistogramList instead. – Szabolcs Jan 25 at 17:03
• @JimB I was really surprised when I hit enter and two comments appeared :-) – Szabolcs Jan 25 at 17:03
• @JimB and Szabolcs: Thank you. I get then a 2 d array of x bin positions and corresponding counts. I will never learn it: how can I pick from that the bin where the maximum occurs. – mrz Jan 25 at 17:13
• A "bin" is an interval. The correct x-position would then be the middle of a bin with maximum cound, wouldn't it? – gwr Jan 25 at 18:47

(* get the bins and counts *)

{binx, counts} = HistogramList[data, {20}];

(* where does the max occur -- can be multiple *)

maxBin = Position[counts, Max[counts]][[1]]

(* {26}  *)

(* what is its bin *)

maxIndex = binx[[maxBin]]

(* {500}  *)


Edit:

(* extract value from list *)

maxIndex[[1]]

(* 500 *)

• And counts[[maxBin]] is then the corresponding value … great – mrz Jan 25 at 17:52
• How can I convert {500} into the value 500? – mrz Jan 25 at 18:22
• maxIndex[[1]] (* 500 *) – David Keith Jan 25 at 18:25

You can also post-process the output of Histogram to extract rectangle coordinates using Cases:

hist = Histogram[data, {20}, Frame -> True, FrameLabel -> {"x", "count"}];
binsandheights = Cases[hist[[1]], Rectangle[{a_, b_}, {c_, d_}, ___] :> {{a, c}, d}, All];


Tallest four rectangles and the associated bins:

binsandheights[[Ordering[-binsandheights[[All, -1]], #]]] & @ 4


{{{500., 520.}, 31.}, {{80., 100.}, 30.},{ {240., 260.}, 28.}, {{980., 1000.}, 28.}}

• Incredible that also this is possible ... – mrz Jan 29 at 10:33

You can use HistogramList to extract the list of x-values for all bins (binSpecs) and their respective counts (binCounts). Note, that there is one more x-value than there are counts:

SeedRandom[2];
data = RandomReal[1000, {1000}];
{ binSpecs, binCounts } = HistogramList[data, {20}];

(* HistogramList will give: { {x0, x1, ..., x50}, { c1, c2, ... , c50 } } *)


We can easily transform the x-values into a list of tuples $$(x_i^\text{left}, x_i^\text{right})$$ giving the left and right x-value for each bin $$i$$. Then there will be as many bins as counts and we can then link each bin to its number of counts (using a rule for this seems quite natural):

bins =  binSpecs // Partition[#, 2, 1] &; (* partition the bin delimiters *)
histogramRules = bins -> binCounts // Thread;


Using MaximalBy we can find the largest bin(s) according to their counts. Note: The function will return a list of bins and their counts if the maximum is not unique:

maxBins = histogramRules ~ MaximalBy ~ Last


{ {500, 520} -> 31 }

There is a unique maximum in this case and we can find the corresponding x-value by:

First @ maxBins /. Rule[binspec_List, val_] :> Mean @ binspec
(* or: maxBins[[1,1]] // Mean *)


510

If the maximum is not unique the bins can be extracted using maxBins[[ All, 1 ]].

Note: Converting the x-values returned by HistogramList to binspecs (e.g. tuples) is imo more robust in the general case, as there may have been more complicated binspecs given.

• Thank you for your solution. – mrz Feb 6 at 16:32
• @mrz You are welcome; your comment inspired me to make the solution a bit more readable (maybe). – gwr Feb 6 at 17:06