6 Ā· Histograms & percentiles
See the whole distribution at once ā and understand why the p99 latency matters more than the average.
A histogram shows what a single number can never tell you ā the full shape of your distribution.
Without this:
Without histograms, you can't detect bimodal distributions, heavy tails, or the log-transform signal hiding in your data.
Two summary numbers ā mean and std dev ā can describe a dataset that is completely Gaussian, or one that is wildly bimodal, or one so right-skewed it spans six orders of magnitude. They cannot tell you which is which. A histogram can.
A histogram bins the data into intervals (called bins), counts the observations in each bin, and draws a bar whose height is proportional to that count (or frequency/density). The result is a visual fingerprint of the distribution's shape.
Bin count is a parameter. Too few bins: fine-grained structure disappears into a single wide block. Too many bins: every bar is just 0 or 1 observation and the plot looks like a comb. Common heuristics:
| Rule | Formula | Best for | |---|---|---| | Sturges | k = ālogā(n)ā + 1 | Small normal-ish datasets | | FreedmanāDiaconis | h = 2Ā·IQR / n^(1/3) | Larger, skewed datasets | | Scott | h = 3.5Ā·Ļ / n^(1/3) | General purpose |
matplotlib's bins='auto' uses the max of Sturges and FreedmanāDiaconis.
A percentile (or quantile) answers: "what value separates the bottom p% of the data from the top (100āp)%?" The 50th percentile is the median. The 25th and 75th are Q1 and Q3. The 99th percentile latency means exactly one thing: 1% of requests take longer than this value.
Python (in browser)
The bell shape confirms normality. Red dashed = mean, blue dotted = median ā for a symmetric distribution they almost coincide. Open /tmp/hist_normal.png in the output panel to view.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
np.percentile(x, q) returns the q-th percentile. The 99th percentile (p99) is the number below which 99% of observations fall ā the 1% slowest requests breach it.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
The same exponential data plotted with 5 vs 50 bins. Five bins hides the long tail completely; fifty bins reveals the decay clearly. Binning choice is an editorial decision. Open /tmp/hist_bins.png to compare.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Three bin-count rules: Sturges (fast, assumes normality), Scott (optimal for Gaussian), FreedmanāDiaconis (robust, preferred for skewed or large datasets). matplotlib's bins='auto' is a good default.
If a request's response time is at the 99th percentile of the distribution, that means...
- A **histogram** reveals shape (skew, modes, tails) that summary statistics hide. Bin count is a parameter ā try a few values.
- The **p-th percentile** is the value below which p% of the data falls. The 99th percentile latency (p99) is the canonical tail-latency metric in production ML systems.
- matplotlib's `bins='auto'` (max of Sturges and FreedmanāDiaconis) is a solid default. Use FreedmanāDiaconis explicitly for large or skewed datasets.
Histograms are the first plot in every EDA notebook ā they reveal modes, skew, and outliers at a glance and tell you whether to apply a log transform. p99 latency targets shape model-serving infrastructure budgets and SLA contracts.
If you remove it: You can't visually detect a bimodal distribution, a heavy tail, or estimate the right transformation (log, sqrt) to apply before training.