or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bins.mdindex.mditerables.mdsearch.mdsequences.mdsets.mdstatistics.mdtransformations.md
tile.json

bins.mddocs/

Bins

Histogram generation and data binning functionality for creating frequency distributions and visualizations. Binning groups discrete samples into consecutive, non-overlapping intervals commonly used in data visualization.

Capabilities

Bin Generator

The bin generator creates histogram bins from data, grouping values into intervals for visualization and analysis.

bin

Creates a new bin generator with default settings.

/**
 * Creates a new bin generator with default settings
 * @returns A configurable bin generator function
 */
function bin(): BinGenerator;

/**
 * @deprecated Use bin() instead
 * Creates a bin generator (legacy alias for bin)
 */
function histogram(): BinGenerator;

interface BinGenerator {
  /**
   * Bins the given iterable of data samples
   * @param data - The data to bin
   * @returns Array of bins, each containing associated elements from input data
   */
  (data: Iterable<any>): Bin[];
  
  /**
   * Sets or gets the value accessor function
   * @param value - Optional accessor function or constant
   * @returns The bin generator (if setting) or current accessor (if getting)
   */
  value(value?: (d: any, i: number, data: any[]) => number): BinGenerator | ((d: any, i: number, data: any[]) => number);
  
  /**
   * Sets or gets the domain (data range) for binning
   * @param domain - Domain array [min, max] or function returning domain
   * @returns The bin generator (if setting) or current domain (if getting)
   */
  domain(domain?: [number, number] | ((values: number[]) => [number, number])): BinGenerator | [number, number] | ((values: number[]) => [number, number]);
  
  /**
   * Sets or gets the threshold generator or explicit thresholds
   * @param thresholds - Number of bins, array of thresholds, or threshold generator function
   * @returns The bin generator (if setting) or current thresholds (if getting)
   */
  thresholds(thresholds?: number | number[] | ((values: number[], min: number, max: number) => number | number[])): BinGenerator | number | number[] | ((values: number[], min: number, max: number) => number | number[]);
}

interface Bin extends Array<any> {
  /** Lower bound of the bin (inclusive) */
  x0: number;
  /** Upper bound of the bin (exclusive, except for the last bin) */
  x1: number;
}

Usage Examples:

import { bin, extent } from "d3-array";

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Basic binning with default settings
const histogram = bin();
const bins = histogram(data);
// Each bin is an array containing the data values that fall within its range
// Each bin has x0 (lower bound) and x1 (upper bound) properties

// Configure bin generator
const customBin = bin()
  .domain([0, 10])  // Set explicit domain
  .thresholds(5);   // Request 5 bins

const customBins = customBin(data);

Bin Configuration Methods

value

Sets the value accessor function for extracting numeric values from data elements.

/**
 * Sets the value accessor function for extracting numeric values
 * @param value - Function to extract numeric values from data elements
 * @returns The bin generator for method chaining
 */
value(value: (d: any, i: number, data: any[]) => number): BinGenerator;

Usage Examples:

import { bin } from "d3-array";

const data = [
  {score: 85}, {score: 92}, {score: 78}, {score: 96}, {score: 73}
];

const histogram = bin()
  .value(d => d.score)  // Extract score property
  .thresholds(3);       // 3 bins

const bins = histogram(data);
// Bins contain the original objects, grouped by their score values

domain

Sets the domain (data range) that should be binned.

/**
 * Sets the domain (data range) that should be binned
 * @param domain - [min, max] array or function that computes domain from values
 * @returns The bin generator for method chaining
 */
domain(domain: [number, number] | ((values: number[]) => [number, number])): BinGenerator;

Usage Examples:

import { bin, extent } from "d3-array";

const data = [1, 2, 3, 4, 5, 15, 16, 17, 18, 19]; // Note the gap

// Default domain uses extent of data
const defaultBin = bin();
// Would create bins covering 1-19

// Custom domain focuses on specific range
const focusedBin = bin()
  .domain([1, 10])      // Only bin values 1-10
  .thresholds(5);

// Values outside domain (15-19) are ignored
const bins = focusedBin(data);

thresholds

Sets the threshold generator or explicit threshold values for binning.

/**
 * Sets the threshold generator or explicit threshold values
 * @param thresholds - Number of bins, explicit threshold array, or generator function
 * @returns The bin generator for method chaining
 */
thresholds(thresholds: number | number[] | ((values: number[], min: number, max: number) => number | number[])): BinGenerator;

Usage Examples:

import { bin, thresholdFreedmanDiaconis, ticks } from "d3-array";

const data = [/* numeric data */];

// Specify number of bins (approximate)
const binByCount = bin().thresholds(10);

// Explicit threshold values
const binExplicit = bin().thresholds([0, 5, 10, 20, 50, 100]);

// Use threshold generator function
const binFreedman = bin().thresholds(thresholdFreedmanDiaconis);

// Custom threshold generator
const binCustom = bin().thresholds((values, min, max) => {
  return ticks(min, max, 8);  // Nice tick values
});

Threshold Generators

Pre-built functions that determine optimal number of bins based on statistical methods.

thresholdSturges

Returns the number of bins according to Sturges' formula.

/**
 * Returns the number of bins according to Sturges' formula
 * @param values - Array of numeric values
 * @returns Number of recommended bins
 */
function thresholdSturges(values: number[]): number;

thresholdFreedmanDiaconis

Returns the number of bins according to the Freedman–Diaconis rule.

/**
 * Returns the number of bins according to the Freedman–Diaconis rule
 * @param values - Array of numeric values
 * @param min - Minimum value in the dataset
 * @param max - Maximum value in the dataset
 * @returns Number of recommended bins
 */
function thresholdFreedmanDiaconis(values: number[], min: number, max: number): number;

thresholdScott

Returns the number of bins according to Scott's normal reference rule.

/**
 * Returns the number of bins according to Scott's normal reference rule
 * @param values - Array of numeric values
 * @param min - Minimum value in the dataset
 * @param max - Maximum value in the dataset
 * @returns Number of recommended bins
 */
function thresholdScott(values: number[], min: number, max: number): number;

Usage Examples:

import { bin, thresholdSturges, thresholdFreedmanDiaconis, thresholdScott } from "d3-array";

const data = [/* large dataset of numeric values */];

// Compare different threshold methods
const sturges = bin().thresholds(thresholdSturges);
const freedman = bin().thresholds(thresholdFreedmanDiaconis);
const scott = bin().thresholds(thresholdScott);

const sturgesBins = sturges(data);
const freedmanBins = freedman(data);
const scottBins = scott(data);

console.log(`Sturges: ${sturgesBins.length} bins`);
console.log(`Freedman-Diaconis: ${freedmanBins.length} bins`);
console.log(`Scott: ${scottBins.length} bins`);

Practical Examples

Basic Histogram

import { bin } from "d3-array";

// Generate sample data
const scores = [
  72, 85, 90, 78, 92, 88, 76, 95, 83, 87,
  91, 79, 86, 89, 94, 81, 77, 93, 84, 80
];

// Create histogram with 5 bins
const histogram = bin()
  .domain([70, 100])  // Score range
  .thresholds(5);     // 5 bins

const bins = histogram(scores);

// Display histogram
bins.forEach((bin, i) => {
  console.log(`Bin ${i}: [${bin.x0}, ${bin.x1}) - ${bin.length} students`);
  console.log(`  Scores: ${bin.join(', ')}`);
});

// Output might be:
// Bin 0: [70, 76) - 2 students
//   Scores: 72
// Bin 1: [76, 82) - 5 students
//   Scores: 78, 76, 79, 81, 77
// etc.

Object Data Histogram

import { bin } from "d3-array";

const transactions = [
  {id: 1, amount: 25.50, category: 'food'},
  {id: 2, amount: 120.00, category: 'shopping'},
  {id: 3, amount: 45.75, category: 'food'},
  {id: 4, amount: 300.00, category: 'rent'},
  {id: 5, amount: 15.25, category: 'food'},
  // ... more transactions
];

// Bin transactions by amount
const amountHistogram = bin()
  .value(d => d.amount)
  .domain([0, 500])
  .thresholds(10);

const amountBins = amountHistogram(transactions);

// Analyze spending patterns
amountBins.forEach((bin, i) => {
  const totalAmount = bin.reduce((sum, t) => sum + t.amount, 0);
  const avgAmount = totalAmount / bin.length;
  
  console.log(`$${bin.x0}-$${bin.x1}: ${bin.length} transactions, avg $${avgAmount.toFixed(2)}`);
});

Time-based Binning

import { bin, timeDay, timeWeek } from "d3-array";

const events = [
  {timestamp: new Date('2023-01-01'), type: 'login'},
  {timestamp: new Date('2023-01-02'), type: 'purchase'},
  {timestamp: new Date('2023-01-03'), type: 'login'},
  // ... more events
];

// Bin events by day
const dailyBins = bin()
  .value(d => d.timestamp.getTime())
  .thresholds((values, min, max) => {
    // Create threshold for each day
    const start = new Date(min);
    const end = new Date(max);
    const thresholds = [];
    
    for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
      thresholds.push(d.getTime());
    }
    
    return thresholds;
  });

const eventsByDay = dailyBins(events);

// Analyze daily activity
eventsByDay.forEach(bin => {
  const date = new Date(bin.x0).toDateString();
  console.log(`${date}: ${bin.length} events`);
});

Dynamic Threshold Selection

import { bin, thresholdFreedmanDiaconis, thresholdSturges, thresholdScott } from "d3-array";

function adaptiveHistogram(data, maxBins = 50) {
  // Try different threshold methods and pick the best one
  const methods = [
    { name: 'sturges', fn: thresholdSturges },
    { name: 'freedman', fn: thresholdFreedmanDiaconis },
    { name: 'scott', fn: thresholdScott }
  ];
  
  let bestBins = null;
  let bestCount = 0;
  
  methods.forEach(method => {
    const histogram = bin().thresholds(method.fn);
    const bins = histogram(data);
    
    // Prefer method that gives reasonable number of bins
    if (bins.length > bestCount && bins.length <= maxBins) {
      bestBins = bins;
      bestCount = bins.length;
    }
  });
  
  return bestBins || bin().thresholds(Math.min(maxBins, Math.ceil(Math.sqrt(data.length))))(data);
}

// Usage
const measurements = [/* large array of measurements */];
const optimalBins = adaptiveHistogram(measurements);

Histogram Statistics

import { bin, mean, deviation } from "d3-array";

function analyzeDistribution(data) {
  const histogram = bin().thresholds(20);
  const bins = histogram(data);
  
  // Calculate statistics for each bin
  const binStats = bins.map(bin => ({
    range: [bin.x0, bin.x1],
    count: bin.length,
    density: bin.length / data.length,
    mean: mean(bin),
    stdDev: deviation(bin)
  }));
  
  // Find most common range
  const maxBin = binStats.reduce((max, bin) => 
    bin.count > max.count ? bin : max
  );
  
  return {
    bins: binStats,
    mostCommon: maxBin,
    totalBins: bins.length
  };
}

const distribution = analyzeDistribution([/* your data */]);
console.log(`Most common range: [${distribution.mostCommon.range.join(', ')}]`);
console.log(`${distribution.mostCommon.count} values (${(distribution.mostCommon.density * 100).toFixed(1)}%)`);