HistogramBins
Mojo struct 🡭
HistogramBins
@memory_only
struct HistogramBinsA binned sample: len(edges) - 1 bins, edges ascending, one entry in values per bin. What histogram_bins() returns and what histogram() draws.
Numeric edges rather than the List[String] range labels this
module stored before. A label like "52.0-57.8" is a
formatted view of a number, and every downstream use – placing a
bar over the interval it actually covers, sharing an x-domain with a
density curve, aligning a marginal histogram with the joint plot it
sits beside – needs the number back. Rounding it to one decimal
place for display and then parsing it again would be a lossy round
trip through a string for no reason.
edges is bins + 1 long, not one (lo, hi) pair per bin, because
a histogram’s bins tile an interval with no gaps and no overlaps:
the pair form can express a gap or an overlap, which is a state
nothing here can draw and every consumer would have to check for.
Unequal widths are fine – the shared edge is exactly what makes
them still a tiling.
Fields
- edges (
List[Float64]): Thebins + 1bin boundaries, strictly ascending. Binicovers[edges[i], edges[i + 1]), except the last, which includesedges[-1]. - values (
List[Float64]): One value per bin, inHistStat’s units.
Implemented traits
AnyType, Copyable, Deinitable, Movable, Sized
Methods
__init__
fn def __init__(out self, var edges: List[Float64], var values: List[Float64])Construct directly from already-computed columns.
Args:
- edges (
List[Float64]): Thebins + 1boundaries, strictly ascending. - values (
List[Float64]): One value per bin. - self (
Self)
Returns:
Self
__len__
fn def __len__(self) -> IntHow many bins there are.
Args:
- self (
Self)
Returns:
Int: len(edges) - 1.
width
fn def width(self, i: Int) -> Float64Bin i’s width.
Args:
- self (
Self) - i (
Int): Bin index,0throughlen(self) - 1.
Returns:
Float64: edges[i + 1] - edges[i].
center
fn def center(self, i: Int) -> Float64Bin i’s midpoint – where a marker or a label for the bin goes.
Computed as lo + (hi - lo) / 2 rather than (lo + hi) / 2:
the two agree to a rounding step for ordinary data, but the sum
form overflows to infinity for edges near Float64’s maximum
and the difference form does not.
Args:
- self (
Self) - i (
Int): Bin index,0throughlen(self) - 1.
Returns:
Float64: The midpoint of [edges[i], edges[i + 1]].
total
fn def total(self) -> Float64The sum of every bin’s value – W for COUNT, 1.0 for PROBABILITY, 100.0 for PERCENT, and a number with no meaning of its own for the two width-normalized stats (sum value[i] * width[i] for those instead).
Args:
- self (
Self)
Returns:
Float64: sum(values).
step_x
fn def step_x(self) -> List[Float64]The x column for drawing this as a staircase: every edge, in order, bins + 1 long. Pair with step_y() and mark_area(step=StepStyle.POST) (or mark_line), which is exactly what histogram() does.
POST is the style that matches: it holds y[i] across
[x[i], x[i + 1]), which is the half-open bin [edges[i], edges[i + 1]). PRE would draw every bar shifted one bin left
and MID half a bin left.
Args:
- self (
Self)
Returns:
List[Float64]: A copy of edges.
step_y
fn def step_y(self) -> List[Float64]The y column for step_x(): every bin’s value, plus the last value repeated so the final plateau has a point to run out to at edges[-1].
StepStyle.POST draws [x[i], x[i + 1]) at y[i] and stops at
the last sample, so without the repeat the rightmost bin would
be a bar with no top.
Args:
- self (
Self)
Returns:
List[Float64]: values with values[-1] appended, bins + 1 long.