Bland.Histogram (Elixir Technical Drawing v0.4.0)

Copy Markdown View Source

Binning helpers for histograms.

Given a list of numeric observations, bin/2 returns the computed {edges, values, density?} triple used by %Bland.Series.Histogram{}.

Bland.histogram/3 calls this for you at series-construction time; you only need bin/2 directly if you want to pre-compute bin counts outside of a figure (e.g. to render a table alongside the plot).

Bin-count strategies

  • integer N — exactly N equal-width bins
  • :sturges⌈1 + log₂(n)⌉ (default)
  • :sqrt⌈√n⌉
  • :scott⌈(max-min) / (3.49·σ·n^(-1/3))⌉
  • :freedman_diaconis⌈(max-min) / (2·IQR·n^(-1/3))⌉

Pass explicit bin_edges: [...] to skip strategy selection entirely.

iex> {edges, counts, _} = Bland.Histogram.bin([1, 2, 2, 3, 3, 3], bins: 3)
iex> {length(edges), counts}
{4, [1, 2, 3]}

Summary

Functions

Bins observations.

Edges computed for observations under the given strategy.

Converts {bin_edges, cumulative_probabilities} into a staircase polyline {xs, ys} suitable for Bland.line/4.

Types

normalize()

@type normalize() :: :count | :pmf | :density | :cmf

opts()

@type opts() :: [
  bins: strategy(),
  bin_edges: [number()],
  density: boolean(),
  normalize: :count | :pmf | :density | :cmf
]

strategy()

@type strategy() :: pos_integer() | :sturges | :sqrt | :scott | :freedman_diaconis

Functions

bin(observations, opts)

@spec bin([number()], opts()) :: {[float()], [number()], normalize()}

Bins observations.

Returns {bin_edges, values, normalize} where:

  • bin_edges is a list of length n_bins + 1
  • values is a list of length n_bins
  • normalize is the requested normalization mode (one of :count, :pmf, :density, :cmf)

Normalizations

  • :count — raw integer counts per bin (default)
  • :pmf — probability mass per bin: count / total. Σ values = 1. Appropriate when bins are unequal width or when you want probabilities rather than densities.
  • :density — probability density: count / (total · bin_width). Σ (values · widths) = 1. Integrates to 1 over the domain.
  • :cmf — cumulative mass function: running sum of PMF values ([C₀, C₀+C₁, ..., 1]). Length matches counts; see Bland.histogram/3 for how this is rendered as a staircase.

Options:

  • :bins — bin-count strategy (default :sturges)
  • :bin_edges — explicit edge list; overrides :bins
  • :normalize:count | :pmf | :density | :cmf (default :count)

  • :density — shorthand for normalize: :density. Kept for backwards compatibility.

Observations that fall outside [bin_edges |> hd, bin_edges |> List.last] are silently dropped.

iex> {_edges, values, :pmf} = Bland.Histogram.bin([1, 2, 2, 3, 3, 3], bins: 3, normalize: :pmf)
iex> Enum.sum(values)
1.0

edges(observations, opts)

@spec edges([number()], opts()) :: [float()]

Edges computed for observations under the given strategy.

staircase(edges, cumulative)

@spec staircase([number()], [number()]) :: {[float()], [float()]}

Converts {bin_edges, cumulative_probabilities} into a staircase polyline {xs, ys} suitable for Bland.line/4.

The returned polyline starts at (edges |> hd, 0.0), steps horizontally across each bin at the previous cumulative level, then jumps vertically at the bin's right edge — the classic empirical CDF shape.

iex> {xs, ys} = Bland.Histogram.staircase([0.0, 1.0, 2.0], [0.5, 1.0])
iex> {xs, ys}
{[0.0, 1.0, 1.0, 2.0, 2.0], [0.0, 0.0, 0.5, 0.5, 1.0]}