How many bins should a histogram have? Sturges, √n and Freedman–Diaconis compared

For 1,000 normal values the common rules give 11 (Sturges), 20 (Rice, Scott), 27 (Freedman–Diaconis, NumPy auto) or 32 (square root) bins. Start with NumPy’s auto rule, then check one coarser and one finer setting.
For 1,000 normal values the common rules suggest 11 (Sturges), 20 (Rice, Scott), 27 (Freedman–Diaconis) and 32 (square root) bins. A good starting point is bins="auto" in NumPy or matplotlib, which picks a width from the data (27 bins here). Then draw one coarser and one finer version: a peak or gap that shows up at only one bin count is probably noise. If the data has a long tail, change the scale (for example, a log axis) before you touch the bin count.
Both plt.hist and pandas.Series.hist use bins=10 unless you pass something else. The examples below ran on 2026-09-28 with NumPy 2.5.3, matplotlib 3.11.2 and pandas 3.0.6.
Five, ten, auto and 200 bins on the same delivery times
Too few bins hide structure, and too many show noise and empty gaps. Here are 1,000 delivery times from two groups: a fast group around 30 minutes and a slow group around 45 minutes.
import numpy as np
rng = np.random.default_rng(7)
# Delivery times (minutes): a fast group and a slow group
x = np.concatenate([rng.normal(30, 4, 600), rng.normal(45, 4, 400)])
for bins in [5, 10, "auto", 200]:
counts, edges = np.histogram(x, bins=bins)
print(f"bins={str(bins):<5} -> {len(counts):>3} bins, width {edges[1] - edges[0]:.2f} min, "
f"empty bins: {(counts == 0).sum()}")
bins=5 -> 5 bins, width 7.66 min, empty bins: 0
bins=10 -> 10 bins, width 3.83 min, empty bins: 0
bins=auto -> 13 bins, width 2.95 min, empty bins: 0
bins=200 -> 200 bins, width 0.19 min, empty bins: 25

- 5 bins: each bar is 7.7 minutes wide. You can tell there is more than one group, but not where the peaks are.
- 10 bins (the default): both groups show up, but the peak positions are still rough.
auto(13 bins): clear peaks near 30 and 45 minutes, with a dip between them.- 200 bins: 25 bins are empty and the bars jump up and down. Most of that is random noise.
Want to click through 5, 200 and auto bins on this same sample yourself? The interactive visualizer has it as a lesson.
Six NumPy rules at 100, 1,000 and 100,000 values
Each rule turns the data size (and sometimes its spread) into a bin count or a bin width. Most of them grow with the cube root of n; Sturges grows only with log2(n). This code prints the number of bins each NumPy rule picks for normal data of different sizes, and for a long-tailed sample:
import numpy as np
rng = np.random.default_rng(42)
rules = ["sqrt", "sturges", "rice", "scott", "fd", "auto"]
def n_bins(x, rule):
return len(np.histogram_bin_edges(x, bins=rule)) - 1
print(f"{'data':<18}" + "".join(f"{r:>9}" for r in rules))
for n in [100, 1_000, 100_000]:
x = rng.normal(50, 10, n)
print(f"{'normal, n=' + format(n, ','):<18}" + "".join(f"{n_bins(x, r):>9}" for r in rules))
x = rng.lognormal(3, 1, 1_000)
print(f"{'lognormal, n=1,000':<18}" + "".join(f"{n_bins(x, r):>9}" for r in rules))
data sqrt sturges rice scott fd auto
normal, n=100 10 8 10 8 9 9
normal, n=1,000 32 11 20 20 27 27
normal, n=100,000 317 18 93 125 162 162
lognormal, n=1,000 32 11 20 33 88 64
The formulas come from the numpy.histogram_bin_edges docs (checked 2026-09-28):
| Rule | Formula | Behavior in the test above |
|---|---|---|
Square root (sqrt) | bins = √n | Grows fastest: 317 bins at n=100,000 |
| Sturges | bins = log2(n) + 1 | Grows slowest: only 18 bins at n=100,000. It assumes normal data |
| Rice | bins = 2 · n^(1/3) | Ignores the spread of the data |
| Scott | width = σ · (24√π / n)^(1/3) | Uses the standard deviation, so outliers affect it |
Freedman–Diaconis (fd) | width = 2 · IQR / n^(1/3) | Uses the interquartile range, so it resists outliers |
auto | Narrower of Sturges and fd, with a cap | Equals fd for normal data from n=1,000 in this test |
Sturges falls behind on large data: at n=100,000 it suggests 18 bins while fd suggests 162. Sturges is the default in R’s hist(), so keep this in mind if you compare charts across tools.
auto also has a cap. For the long-tailed sample, fd asks for 88 bins but auto returns 64. In the NumPy 2.5.3 source (checked 2026-09-28), auto never makes bins narrower than half the sqrt rule’s width (max(fd_bw, sqrt_bw / 2)). That limits it to about twice the sqrt bin count, here 2 × 32 = 64.
Long-tailed data reads better on a log scale
When a few values are far larger than the rest, any bin count leaves most bars squeezed on the left:

On the raw scale, auto gives 64 bins and almost all of the data sits in the first few bars. After np.log10, auto needs only 24 bins and the shape is easy to read. Income, prices, file sizes, and response times often look like this.
Mistakes that change what the chart says
- Keeping the default
bins=10without checking it. Setbins="auto"or a number you have compared. - Overlaying two groups with different bin edges. Pass the same
binsarray to both, for exampleedges = np.histogram_bin_edges(all_data, bins="auto"). - Reading meaning into one setting. Check that a peak or gap survives a coarser and a finer bin count.
- Using many bins on small data. With 50 normal points and 30 bins, 53–63% of the bars held 0 or 1 values across five random samples.
If you are new to the chart itself, What is a histogram? starts from the basics.