Python bindings for Boost::Histogram ([source][Boost::Histogram source]), a C++14 library. This is one of the fastest libraries for histogramming, while still providing the power of a full histogram object. See what's new.
For end users interested in analysis, see Hist, a first-party analyst-friendly histogram library that extends boost-histogram with named axes, many new shortcuts including UHI+, plotting shortcuts, and more.
Text intro (click to expand)
import boost_histogram as bh
# Compose axis however you like; this is a 2D histogram
hist = bh.Histogram(
bh.axis.Regular(2, 0, 1),
bh.axis.Regular(4, 0.0, 1.0),
)
# Filling can be done with arrays, one per dimension
hist.fill(
[0.3, 0.5, 0.2],
[0.1, 0.4, 0.9],
)
# NumPy array view into histogram counts, no overflow bins
values = hist.values()
# Make a new histogram with just the second axis, summing over the first, and
# rebinning the second into larger bins:
h2 = hist[::sum, ::bh.rebin(2)]
We support the uhi PlottableHistogram protocol, so boost-histogram/Hist histograms can be plotted via any compatible library, such as mplhep.
Simplified list of features (click to expand)
metadata=...
)
bh.axis.Regular(n, start, stop, ...)
: Make a regular axis. Options listed below.
overflow=False
: Turn off overflow binunderflow=False
: Turn off underflow bingrowth=True
: Turn on growing axis, bins added when out-of-range items addedcircular=True
: Turn on wrapping, so that out-of-range values wrap around into the axistransform=bh.axis.transform.Log
: Log spacingtransform=bh.axis.transform.Sqrt
: Square root spacingtransform=bh.axis.transform.Pow(v)
: Power spacingbh.axis.Integer(start, stop, *, underflow=True, overflow=True, growth=False, circular=False)
: Special high-speed version of regular
for evenly spaced bins of width 1bh.axis.Variable([start, edge1, edge2, ..., stop], *, underflow=True, overflow=True, circular=False)
: Uneven bin spacingbh.axis.IntCategory([...], *, growth=False)
: Integer categoriesbh.axis.StrCategory([...], *, growth=False)
: String categoriesbh.axis.Boolean()
: A True/False axis.index(value)
: The index at a point (or points) on the axis.value(index)
: The value for a fractional bin (or bins) in the axis.bin(i)
: The bin edges (continuous axis) or a bin value (discrete axis).centers
: The N bin centers (if continuous).edges
: The N+1 bin edges (if continuous).extent
: The number of bins (including under/overflow).metadata
: Anything a user wants to store.traits
: The options set on the axis.size
: The number of bins (not including under/overflow).widths
: The N bin widthsbh.storage.Double()
: Doubles for weighted values (default)bh.storage.Int64()
: 64-bit unsigned integersbh.storage.Unlimited()
: Starts small, but can go up to unlimited precision ints or doubles.bh.storage.AtomicInt64()
: Threadsafe filling, experimental. Does not support growing axis in threads.bh.storage.Weight()
: Stores a weight and sum of weights squared.bh.storage.Mean()
: Accepts a sample and computes the mean of the samples (profile).bh.storage.WeightedMean()
: Accepts a sample and a weight. It computes the weighted mean of the samples.bh.accumulator.Sum
: High accuracy sum (Neumaier) - used by the sum method when summing a numerical histogrambh.accumulator.WeightedSum
: Tracks a weighted sum and variancebh.accumulator.Mean
: Running count, mean, and variance (Welfords's incremental algorithm)bh.accumulator.WeightedMean
: Tracks a weighted sum, mean, and variance (West's incremental algorithm)h.ndim
: The number of dimensionsh.size or len(h)
: The number of bins+
: Add two histograms (storages must match types currently)*=
: Multiply by a scaler (not all storages) (hist * scalar
and scalar * hist
supported too)/=
: Divide by a scaler (not all storages) (hist / scalar
supported too).kind
: Either bh.Kind.COUNT
or bh.Kind.MEAN
, depending on storage.sum(flow=False)
: The total count of all bins.project(ax1, ax2, ...)
: Project down to listed axis (numbers). Can also reorder axes..to_numpy(flow=False, view=False)
: Convert to a NumPy style tuple (with or without under/overflow bins).view(flow=False)
: Get a view on the bin contents (with or without under/overflow bins).values(flow=False)
: Get a view on the values (counts or means, depending on storage).variances(flow=False)
: Get the variances if available.counts(flow=False)
: Get the effective counts for all storage types.reset()
: Set counters to 0.empty(flow=False)
: Check to see if the histogram is empty (can check flow bins too if asked).copy(deep=False)
: Make a copy of a histogram.axes
: Get the axes as a tuple-like (all properties of axes are available too)
.axes[0]
: Get the 0th axis.axes.edges
: The lower values as a broadcasting-ready array.axes.centers
: The centers of the bins broadcasting-ready array.axes.widths
: The bin widths as a broadcasting-ready array.axes.metadata
: A tuple of the axes metadata.axes.size
: A tuple of the axes sizes (size without flow).axes.extent
: A tuple of the axes extents (size with flow).axes.bin(*args)
: Returns the bin edges as a tuple of pairs (continuous axis) or values (describe).axes.index(*args)
: Returns the bin index at a value for each axis.axes.value(*args)
: Returns the bin value at an index for each axisv = h[b]
: Access bin content by index numberv = h[{0:b}]
: All actions can be represented by axis:item
dictionary instead of by position (mostly useful for slicing)h2 = h[a:b]
: Access a slice of a histogram, cut portions go to flow bins if presenth2 = h[:, ...]
: Using :
and ...
supported just like NumPyh2 = h[::sum]
: Third item in slice is the "action"h[...] = array
: Set the bin contents, either include or omit flow binsbh.loc(v)
: Supply value in axis coordinates instead of bin numberbh.underflow
: The underflow bin (use empty beginning on slice for slicing instead)bh.overflow
: The overflow bin (use empty end on slice for slicing instead)sum
: Remove axes via projection; if limits are given, use thosebh.rebin(n)
: Rebin an axisbh.numpy
provides faster drop in replacements for NumPy histogram functions.view()
.to_numpy()
You can install this library from PyPI with pip:
python3 -m pip install boost-histogram
All the normal best-practices for Python apply; Pip should not be very old (Pip
9 is very old), you should be in a virtual environment, etc. Python 3.6+ is
required; for older versions of Python (3.5 and 2.7), 0.13
will be installed
instead, which is API equivalent to 1.0, but will not be gaining new features.
The easiest way to get boost-histogram is to use a binary wheel, which happens when you run the above command on a supported platform. Wheels are produced using cibuildwheel; all common platforms have wheels provided in boost-histogram:
| System | Arch | Python versions | PyPy versions | |---------|-----|------------------|--------------| | ManyLinux1 (custom GCC 9.2) | 32 & 64-bit | 3.6, 3.7, 3.8 | | | ManyLinux2010 | 32 & 64-bit | 3.6, 3.7, 3.8, 3.9 | (64-bit) 7.3: 3.7 | | ManyLinux2014 | 32 & 64-bit | 3.10 | | | ManyLinux2014 | ARM64 | 3.6, 3.7, 3.8, 3.9, 3.10 | | | MuslLinux11 | 64-bit | 3.6, 3.7, 3.8, 3.9, 3.10 | | | macOS 10.9+ | 64-bit | 3.6, 3.7, 3.8, 3.9, 3.10 | 7.3: 3.7 | | macOS Universal2 | Arm64 | 3.8, 3.9, 3.10 | | | Windows | 32 & 64-bit | 3.6, 3.7, 3.8, 3.9, 3.10 | (64-bit) 7.3: 3.7 |
manylinux2014
. PowerPC or IBM-Z available on request, or manylinux_2_24
, or musllinux_1_1
.If you are on a Linux system that is not part of the "many" in manylinux or musl in musllinux, such as ClearLinux, building from source is usually fine, since the compilers on those systems are often quite new. It will just take longer to install when it is using the sdist instead of a wheel. All dependencies are header-only and included.
The boost-histogram package is available on conda-forge, as well. All supported variants are available.
conda install -c conda-forge boost-histogram
For a source build, for example from an "SDist" package, the only requirements are a C++14 compatible compiler. The compiler requirements are dictated by Boost.Histogram's C++ requirements: gcc >= 5.5, clang >= 3.8, or msvc >= 14.1. You should have a version of pip less than 2-3 years old (10+).
Boost is not required or needed (this only depends on included header-only dependencies). You can install directly from GitHub if you would like.
python -m pip install git+https://github.com/scikit-hep/boost-histogram.git@develop
See CONTRIBUTING.md for details on how to set up a development environment.
We would like to acknowledge the contributors that made this project possible (emoji key):
This project follows the all-contributors specification.
The official documentation is here, and includes a quickstart.
This library was primarily developed by Henry Schreiner and Hans Dembinski.
Support for this work was provided by the National Science Foundation cooperative agreement OAC-1836650 (IRIS-HEP) and OAC-1450377 (DIANA/HEP). Any opinions, findings, conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of the National Science Foundation.