15
$\begingroup$

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

Mathematica graphics

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]
$\endgroup$

4 Answers 4

17
$\begingroup$

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

enter image description here

$\endgroup$
8
  • $\begingroup$ (Note, I kept the +2 on the height of the line.) $\endgroup$ Jan 18, 2012 at 22:03
  • $\begingroup$ Isn't Histogram supposed to return 300 bins with this command? HistogramList[returns, 300, "PDF"][[2]] // Length says it's 413. Any idea? $\endgroup$ Jan 18, 2012 at 22:23
  • 3
    $\begingroup$ 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.) $\endgroup$ Jan 18, 2012 at 22:27
  • 2
    $\begingroup$ That's totally undocumented. Doc page says "n: use n bins". $\endgroup$ Jan 18, 2012 at 22:32
  • 6
    $\begingroup$ OK, question then is: Why isn't it documented? $\endgroup$ Jan 18, 2012 at 22:38
8
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ Oh that internet delay! $\endgroup$
    – Andy Ross
    Jan 18, 2012 at 22:00
  • $\begingroup$ @AndyRoss Ha, beat you by a minute ;-) $\endgroup$ Jan 18, 2012 at 22:13
  • $\begingroup$ Probably the time incurred by using Part instead of the 2nd argument to Ordering :) $\endgroup$
    – Andy Ross
    Jan 18, 2012 at 22:15
4
$\begingroup$

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
$\endgroup$
5
  • $\begingroup$ What do you have against Max? $\endgroup$ Jan 18, 2012 at 22:04
  • $\begingroup$ 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. $\endgroup$
    – Andy Ross
    Jan 18, 2012 at 22:05
  • $\begingroup$ @AndyRoss There's Ordering for that (WhichIsMax I mean). Ordering[{2, 4, 1, 7, 3}, -1] ==> {4} $\endgroup$ Jan 18, 2012 at 22:08
  • $\begingroup$ 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! $\endgroup$
    – Andy Ross
    Jan 18, 2012 at 22:09
  • 7
    $\begingroup$ No, don't use Part there. Use Ordering's second argument; it's much faster. It prevents Ordering from performing an unnecessary full sort. $\endgroup$ Jan 18, 2012 at 22:11
2
$\begingroup$

You could just fish the data from the histogram itself :

maxFreq=Max[Flatten[h[[1, 2, 2, 2]]][[All, 2, 2]]]
$\endgroup$
2
  • 3
    $\begingroup$ There is at least some danger in doing this however since the internal structure of the object may change between versions. $\endgroup$
    – Andy Ross
    Jan 19, 2012 at 0:22
  • $\begingroup$ 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. $\endgroup$
    – Tim Mayes
    Jan 19, 2012 at 5:52

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.