# How can I extract the maximum value from a Histogram?

In Mathematica 8.04 I've created a histogram of returns on a stock using:

returns = FinancialData["SP500", "Return", {Date[] - {5, 0, 0, 0, 0, 0}, Date[]}, "Value"];
μ = Mean[returns];
h = Histogram[returns, 300, "PDF"];


where "returns" is a list of the daily returns, and I want 300 bins in the probability density method. Next, I would like to draw a line that represents the mean of the returns so I use:

meanLine = Graphics[{Thick, Darker[Green], Line[{{μ, 0}, {μ, maxFreq + 2}}]}];


The problem is that I need to calculate the highest y-value for the line, which should be equal to the count of the data points in the bin with the most points (I've called this maxFreq above). I am currently setting this value manually because I don't know how to extract it from the histogram (h). Note that the x-coordinate of this line (μ) is simply the mean of the returns.

I've tried looking at FullForm[h] to see if I could figure out how to extract the data. Buried within that output is the following:

List[List[Rectangle[List[-0.0015, 0.], List[-0.001, 54.0111]


which shows that I want to set maxFreq = 54.0111. So, I suppose that I want to use the Max function, but I don't know how to access the heights of each bin. I think that I need to use some variation of the Part function, but I can't figure out how. Any clues would be appreciated.

Here is the code that will generate what I'm looking for, but maxFreq is manually entered:

returns = FinancialData["SP500", "Return", {Date[] - {5, 0, 0, 0, 0, 0}, Date[]}, "Value"];
μ = Mean[returns];
h = Histogram[returns, 300, "PDF"];
maxFreq = 54;
meanLine = Graphics[{Thick, Darker[Green],Line[{{μ, 0}, {μ, maxFreq + 2}}]}];
Show[h, meanLine]

-

## 4 Answers

As mentioned by others, use HistogramList. You can even use the resulting information to generate the plot without recomputing the information:

{bins, heights} = HistogramList[returns, 300, "PDF"];
maxFreq = Max[heights];
Histogram[returns, {bins}, heights &,
Epilog -> {{Thick, Darker[Green],
Line[{{μ, 0}, {μ, maxFreq + 2}}]}}]


-
(Note, I kept the +2 on the height of the line.) –  Brett Champion Jan 18 '12 at 22:03
Isn't Histogram supposed to return 300 bins with this command? HistogramList[returns, 300, "PDF"][[2]] // Length says it's 413. Any idea? –  Sjoerd C. de Vries Jan 18 '12 at 22:23
It's a fuzzy 300, so that the boundaries are on "nice" numbers. {"Raw", 300} will use 300, but then the boundaries won't be at nice values. (Maybe that's not an issue with 300 bins, though.) –  Brett Champion Jan 18 '12 at 22:27
That's totally undocumented. Doc page says "n: use n bins". –  Sjoerd C. de Vries Jan 18 '12 at 22:32
OK, question then is: Why isn't it documented? –  Sjoerd C. de Vries Jan 18 '12 at 22:38

If you have version 8 you could use HistogramList. It returns a list of bins and a list of heights for those bins.

HistogramList[returns, 300, "PDF"][[2]] // Max // N

(* ===> 54.01111994 *)


For those with versions <8: you could use the third argument of Histogram to make a kind of poor-man's HistogramList:

Reap[Histogram[returns, 300, (Sow[{#1, #2}]; #2) &];]


returns a list of bins and counts. In this case, you don't use counts but want probability density (PDF), so you have to calculate that from the bin size and the counts.

-
Oh that internet delay! –  Andy Ross Jan 18 '12 at 22:00
@AndyRoss Ha, beat you by a minute ;-) –  Sjoerd C. de Vries Jan 18 '12 at 22:13
Probably the time incurred by using Part instead of the 2nd argument to Ordering :) –  Andy Ross Jan 18 '12 at 22:15

You can use HistogramList to generate the bins and their heights corresponding to a histogram and then use Sort[hts][[-1]] to obtain your result.

With[{res = N@HistogramList[returns, 300, "PDF"][[2]]}, Sort[res][[-1]]]

Out[104]= 54.0111

-
What do you have against Max? –  Brett Champion Jan 18 '12 at 22:04
Nothing in particular :) It began with my wishing for the R function WhichIsMax which gives the index of the maximum value. I had originally written the code in that way and then posted before fully simplifying it. –  Andy Ross Jan 18 '12 at 22:05
@AndyRoss There's Ordering for that (WhichIsMax I mean). Ordering[{2, 4, 1, 7, 3}, -1] ==> {4} –  Sjoerd C. de Vries Jan 18 '12 at 22:08
Exactly. The original code snippet had Ordering[res][[-1]]. This should teach me to avoid working with R and Mathematica at the same time while posting! –  Andy Ross Jan 18 '12 at 22:09
No, don't use Part there. Use Ordering's second argument; it's much faster. It prevents Ordering from performing an unnecessary full sort. –  Sjoerd C. de Vries Jan 18 '12 at 22:11

You could just fish the data from the histogram itself :

maxFreq=Max[Flatten[h[[1, 2, 2, 2]]][[All, 2, 2]]]

-
There is at least some danger in doing this however since the internal structure of the object may change between versions. –  Andy Ross Jan 19 '12 at 0:22
Thanks, that is what I was trying to get at, but it looks like HistogramList will be a lot easier and I'll remember what it means in a few months. –  Tim Mayes Jan 19 '12 at 5:52