2
$\begingroup$

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

enter image description here

$\endgroup$
  • 1
    $\begingroup$ Use HistogramList. $\endgroup$ – JimB Jan 25 at 17:03
  • 1
    $\begingroup$ Use HistogramList instead. $\endgroup$ – Szabolcs Jan 25 at 17:03
  • 1
    $\begingroup$ @JimB I was really surprised when I hit enter and two comments appeared :-) $\endgroup$ – Szabolcs Jan 25 at 17:03
  • $\begingroup$ @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. $\endgroup$ – mrz Jan 25 at 17:13
  • 1
    $\begingroup$ A "bin" is an interval. The correct x-position would then be the middle of a bin with maximum cound, wouldn't it? $\endgroup$ – gwr Jan 25 at 18:47
3
$\begingroup$

Following the comments:

(* 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 *)
$\endgroup$
  • $\begingroup$ And counts[[maxBin]] is then the corresponding value … great $\endgroup$ – mrz Jan 25 at 17:52
  • $\begingroup$ How can I convert {500} into the value 500? $\endgroup$ – mrz Jan 25 at 18:22
  • $\begingroup$ maxIndex[[1]] (* 500 *) $\endgroup$ – David Keith Jan 25 at 18:25
2
$\begingroup$

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

$\endgroup$
  • $\begingroup$ Incredible that also this is possible ... $\endgroup$ – mrz Jan 29 at 10:33
1
$\begingroup$

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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.