Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

So I wanted to create a Histogram with a custom number of bins. Luckily there is a simple function for this in the form of Histogram[data, n] where n specifies the number of bins. There is even an example of using it in the documentation:

data = RandomVariate[NormalDistribution[0, 1], 200];
Histogram[data, 5]

Problem is that this doesn't produce a Histogram with five bins but with seven bins:

Mathematica graphics

Histogram[data, 6]still gives seven bins:

Mathematica graphics

Histogram[data, 7] also gives seven bins:

Mathematica graphics

But Histogram[data, 10] gives thirteen bins:

Mathematica graphics

Now I am utterly confused. Is this a bug or have I misunderstood something completely? How would I go about producing a Histogram with five bins?

share
1  
Hmmm... A list with a single element is the bin width, not an integer as I thought. I don't have mma with me right now to test it out, but I think there's an explanation for it. This seems too fundamental to have a bug –  rm -rf Jun 30 '12 at 17:01
2  
This is a documentation bug, not the OP's fault! The documentation indeed says literally (first example under Scope): "Specify the number of bins to use"... –  Jens Jun 30 '12 at 17:01
1  
In the example above the bins are either 1 or 1/2 wide so I suspect that Mathematica adjusts the number of bins in order to get "nice" widths similar to for example FindDivisions. –  Heike Jun 30 '12 at 18:08

4 Answers 4

up vote 11 down vote accepted

Under mma 8 you can use the undocumented {"Raw", n} bin specification to get exactly the number of bins you would like. Otherwise the bin widths and boundaries are chosen to be "nice" numbers.

Here is an example:

data = RandomVariate[NormalDistribution[0, 1], 200];
Histogram[data, {"Raw", 5}]

Example histogram

(I saw this first in a comment by Brett Champion to the answer here.)

share
    
Good memory! I forgot about that exchange (as did Sjoerd)... would've saved me some time trying to wade through the internals to see how it is implemented –  rm -rf Jun 30 '12 at 21:28
    
+1, good to know. Doesn't work on v.7 I confirm. –  Chris Degnen Jun 30 '12 at 21:45

This is known and it seems it is intentional. Even on the doc page of Histogram you can find examples of this behavior. It looks like the number specification is only seen as an order of magnitude indicator. A workaround would be to specify bin lists yourself.

Histogram[data, {-2, 3, 1}]

Mathematica graphics

share
2  
But bspec clearly says "use n bins"... The documentation must be wrong then? I'm surprised I've never come across this given how much I use histograms... Probably because I always specify the bin widths for uniformity across datasets –  rm -rf Jun 30 '12 at 17:02
    
+1 and congratulations for reaching 9966. –  Jens Jun 30 '12 at 17:45
1  
Mathematica used to have a histogram option called ApproximateIntervals which could be used to set the interval boundaries to be simple numbers or not. 'Simple numbers' seems to be the only behaviour now. You have to set them yourself now if you want specific intervals. Here's the old documentation page: reference.wolfram.com/mathematica/Histograms/ref/Histogram.html –  Chris Degnen Jun 30 '12 at 18:21
    
@R.M I know I've seen this a couple of years ago. May have even asked a question about it myself on mathgroup, but couldn't find it right now. I agree the documentation is incorrect here. –  Sjoerd C. de Vries Jun 30 '12 at 19:29
    
@R.M 't was here –  Sjoerd C. de Vries Jun 30 '12 at 21:48

Looking through the internal code for Histogram and following the rabbit hole, this behaviour is clearly intentional and the documentation is definitely misleading. The code for Histogram has a "main" function that looks something like the following:

mainFunction[args__, o : OptionsPattern[]] := 
 Block[{data, stuff, width, height},
    data = First@{args};
    stuff = Rest@{args};
    {width, height} = Switch[Length@stuff,
            0, {Automatic, Automatic},
            1, {First@stuff, Automatic},
            2, stuff
        ];
    ...
  ]

If you continue down other related functions, you'll observe that nowhere do they interpret the argument as number of bins, but only as widths, which are then smoothed with a default smoothing function.

Hence, even though the documentation says that using n for bspec uses n bins, the implementation does not reflect it.

share

As an alternative to Sjoerd C. de Vries answer, you could construct your own histogram with the numbers of bins you want to have with BinCounts Just as an easy example (I am sure it can be better written and a lot of things can be done better):

data = RandomVariate[NormalDistribution[0, 1], 200];      
startValue=-2.5;
endValue=3.5;
binWidth=1;
scale=Table[startValue+i*binWidth,{i,0,(endValue-startValue)/binWidth-1}](*shift the bin center as you like!*);
binnedData=BinCounts[data,{startValue,endValue,binWidth}];
forPlot=Transpose[{scale,binnedData}];

By using

ListPlot[forPlot,InterpolationOrder->0,Filling->Axis,Joined→True]

You will get:

HistogramWithBinCounts

share

This site is currently not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .