# Histogram Chart Maker

Paste a list of numbers and render an SVG histogram. Auto bin rules or an explicit bin count/width, count, percent, density or cumulative bars, mean and median markers.

## Run it

- **CLI:** `gizza tool histogram-chart "12
15
15
17
18
18
19
21
24
28"`
- **Web:** https://gizza.ai/tools/histogram-chart/
- **Agents:** machine-readable descriptor (parameters JSON Schema) at https://gizza.ai/tools/histogram-chart/tool.json

## Inputs

- `data` — Numbers _(field)_
- `bin_method` — Binning method _(field)_
- `bins` — Bin count (for exact bin count) _(field)_
- `bin_width` — Bin width (for exact bin width) _(field)_
- `range_min` — Range minimum _(field)_
- `range_max` — Range maximum _(field)_
- `normalize` — Bars measure _(field)_
- `right_closed` — Right-closed intervals (a, b] _(field)_
- `show_values` — Label each bar with its value _(field)_
- `show_mean` — Show mean marker _(field)_
- `show_median` — Show median marker _(field)_
- `normal_curve` — Overlay normal curve _(field)_
- `rug` — Show rug plot _(field)_
- `grid` — Show grid lines _(field)_
- `orientation` — Orientation _(field)_
- `title` — Chart title _(field)_
- `x_label` — Value-axis label _(field)_
- `y_label` — Measurement-axis label _(field)_
- `width` — SVG width _(field)_
- `height` — SVG height _(field)_
- `color` — Bar colour _(field)_
- `opacity` — Bar opacity _(field)_
- `theme` — Theme _(field)_
- `precision` — Decimal places _(field)_
- `output` — Output _(field)_

## Output

- Histogram output (text)

## Query parameters

Open the tool pre-filled and auto-run via URL:

- `data` — Numbers
- `bin_method` — Binning method
- `bins` — Bin count (for exact bin count)
- `bin_width` — Bin width (for exact bin width)
- `range_min` — Range minimum
- `range_max` — Range maximum
- `normalize` — Bars measure
- `right_closed` — Right-closed intervals (a, b]
- `show_values` — Label each bar with its value
- `show_mean` — Show mean marker
- `show_median` — Show median marker
- `normal_curve` — Overlay normal curve
- `rug` — Show rug plot
- `grid` — Show grid lines
- `orientation` — Orientation
- `title` — Chart title
- `x_label` — Value-axis label
- `y_label` — Measurement-axis label
- `width` — SVG width
- `height` — SVG height
- `color` — Bar colour
- `opacity` — Bar opacity
- `theme` — Theme
- `precision` — Decimal places
- `output` — Output

Example: `https://gizza.ai/tools/histogram-chart/?data=12%0A15%0A15%0A17%0A18%0A18%0A19%0A21%0A24%0A28&bin_method=auto&bins=10&bin_width=5&range_min=0&range_max=100&normalize=count&right_closed=true&show_values=true&show_mean=true&show_median=true&normal_curve=true&rug=true&grid=true&orientation=vertical&title=Response%20times&x_label=Latency%20%28ms%29&y_label=Requests&width=800&height=480&color=%232563eb&opacity=0.9&theme=light&precision=4&output=svg`

---

## About this tool

Histogram Chart Maker turns a pasted column of numbers into a histogram: it groups the values into bins and draws one bar per bin. Use it to see the shape of a distribution — response times, test scores, prices, measurement error, file sizes — before you commit to a dashboard or a report.

Paste values one per line, or separated by commas, tabs, semicolons, or spaces. A leading header row of text is ignored, so a column copied straight out of a spreadsheet works as-is.

Bin edges come from whichever method suits the data:

- **Auto** takes the finer of Freedman-Diaconis and Sturges — a good default for most data.
- **A named rule** — Sturges, Scott, Freedman-Diaconis, Rice, Doane, or square-root — when you need to match a textbook or a statistics package.
- **An exact bin count**, when you want, say, exactly 10 bars.
- **An exact bin width**, when the bins have to mean something — 10-point score bands, 5 ms latency buckets, decade-wide age groups.

Bars can measure raw counts, relative frequency, percent, density, or a running cumulative count or percent. Switch `output` from `svg` to `table`, `csv`, or `json` when you want the frequency table and summary statistics instead of the picture.

### Worked example

Paste these 20 latency measurements:

```
12
15
15
17
18
18
19
21
24
28
31
33
34
34
36
39
41
44
48
55
```

Set `bin_method=width`, `bin_width=10`, `range_min=0`, `range_max=60`, and `output=table`. The range is fixed at 0–60 rather than the data's own 12–55, so the bins land on round numbers. You get six bins and this frequency table:

```
Bin        Count  Percent  Cumulative %  Count
---------  -----  -------  ------------  -----
[0, 10)    0      0        0             0
[10, 20)   7      35       35            7
[20, 30)   3      15       50            3
[30, 40)   6      30       80            6
[40, 50)   3      15       95            3
[50, 60]   1      5        100           1
```

Switch `output` back to `svg` for the same six bars as a chart. The `[10, 20)` bin is the tallest at 7 of 20 values (35%), and the last bin is written `[50, 60]` because the top bin always closes on the upper edge so the maximum has somewhere to go.

### Limits and edge cases

- Input is capped at 100,000 numbers, and at least 2 are needed. Bin count is capped at 500; an over-fine `bin_width` is rejected with the bin count it would have produced, rather than silently truncated.
- Bins are left-closed `[a, b)` by default, with the final bin closing on the maximum. Set `right_closed` for `(a, b]` intervals, where the first bin instead closes on the minimum.
- `range_min` / `range_max` clip the chart: values outside the range are excluded from every count and reported separately as `excluded` in the `table` and `json` output.
- If every value is identical the range is widened slightly so the chart still has an axis.
- The normal-curve overlay is skipped in the two cumulative modes, where a density curve has no meaning.
- Output is a standalone, deterministic SVG — no fonts, images, scripts, or external plotting libraries are loaded, and the same input always produces byte-identical markup.

## FAQ

<details>
<summary>How many bins should I use?</summary>

Start with `bin_method=auto`, which picks the finer of Freedman-Diaconis and Sturges, then adjust. Too few bins hide structure such as a second peak; too many turn the chart into noise, with most bars at a count of one. Freedman-Diaconis uses the interquartile range, so it copes well with skewed data and outliers; Sturges assumes roughly normal data and is gentle on small samples; Doane corrects Sturges for skew. If the bins have to carry meaning to a reader — score bands, price brackets, 5 ms buckets — use `bin_method=width` with an exact width instead of any rule.

</details>

<details>
<summary>What is the difference between count, percent, and density?</summary>

`count` plots the raw number of values in each bin. `relative` plots that as a fraction of the total and `percent` as a percentage, which lets you compare two datasets of different sizes on the same scale. `density` divides by both the total and the bin width, so the bars integrate to 1 — that is the mode to use when you want to overlay the normal curve, or to compare histograms drawn with different bin widths. `cumulative_count` and `cumulative_percent` plot a running total instead, which answers "how many values are at or below this point".

</details>

<details>
<summary>Which bin does a value sitting exactly on an edge go into?</summary>

By default bins are left-closed, written `[a, b)`: a value equal to `b` belongs to the next bin up, and only the final bin includes its upper edge so the maximum is counted. That is the convention numpy, pandas, and most statistics packages use. Turn on `right_closed` for the opposite convention `(a, b]`, common in classroom and spreadsheet examples, where the edge value falls in the lower bin and the first bin includes the minimum. With 0, 5, 10 split into two bins, the default puts 5 in the upper bin and `right_closed` puts it in the lower one.

</details>

<details>
<summary>Can I fix the axis range instead of using the data's minimum and maximum?</summary>

Yes — set `range_min` and `range_max`. The bins are then laid out across that range rather than from the smallest to the largest value, which is how you get round edges like 0–100 instead of 12.3–98.7, and how you draw two histograms on the same axis so they can be compared. Values outside the range are dropped from the counts and reported as `excluded` in the `table` and `json` output, so a clipped outlier is never silently lost.

</details>

<details>
<summary>How do I save the chart or reuse the numbers?</summary>

The default `svg` output is plain SVG markup. Save it to a `.svg` file, drop it into HTML or a Markdown workflow that allows inline SVG, or open it in a vector editor — it is self-contained, so nothing loads from the network. When you want the numbers rather than the picture, `table` gives a readable frequency table with summary statistics (n, min, max, mean, median, standard deviation, quartiles), `csv` gives the same table with one row per bin for a spreadsheet, and `json` gives the bins plus stats for a script.

</details>

## Related tools

- [Boxplot Chart Generator](https://gizza.ai/tools/boxplot-chart/): Paste values or grouped CSV data and render a box-and-whisker SVG with quartiles, whiskers, mean markers, notches, outliers, and summary stats.
- [Analyze a Chat or IRC Log](https://gizza.ai/tools/chat-log-analyzer/): Paste an IRC or chat log and get stats in your browser: who talked most, activity by hour and weekday, top words, links shared, and joins/parts/quits.
- [Correlated sample generator](https://gizza.ai/tools/correlated-sample-generator/): Generate multivariate-normal sample data from a covariance or correlation matrix, with seeded CSV, TSV, JSON or stats output.
- [Frequency distribution](https://gizza.ai/tools/frequency-distribution/): Build a character, byte, or n-gram frequency table from text or hex, with counts and percentages, ranked most to least frequent — in your browser. Nothing is uploaded.
- [Z-Score Normalize](https://gizza.ai/tools/z-score-normalize/): Standardize a list of numbers with z-score, min-max, max-abs, or robust median/IQR scaling. Population or sample standard deviation, private and browser-local.
