Skip to content

Commit bad4883

Browse files
committed
feat: new minimal api
1 parent 31e956b commit bad4883

39 files changed

Lines changed: 1664 additions & 7898 deletions

README.md

Lines changed: 96 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,132 +2,155 @@
22

33
**Optimal Binning Histograms for Python**
44

5-
Khisto is a Python library for creating histograms and cumulative distribution functions (ECDFs) using the **Khiops optimal binning algorithm**. Unlike standard histograms that use fixed-width bins or simple heuristics, Khisto automatically determines the optimal number of bins and their variable widths to best represent the underlying data distribution.
6-
7-
It provides a core Array API for data analysis and drop-in replacements for **Matplotlib** and **Plotly** plotting functions.
5+
Khisto is a Python library for creating histograms using the **Khiops optimal binning algorithm**. Unlike standard histograms that use fixed-width bins or simple heuristics, Khisto automatically determines the optimal number of bins and their variable widths to best represent the underlying data distribution.
86

97
## Features
108

119
- **Optimal Binning**: Uses the MODL (Minimum Description Length) principle to find the best discretization.
1210
- **Variable-Width Bins**: Captures dense regions with fine bins and sparse regions with wider bins.
13-
- **Array API Support**: Works with NumPy, PyTorch, JAX, CuPy, and more (via `narwhals` and `array-api-compat`).
14-
- **Plotting Integrations**:
15-
- **Matplotlib**: `khisto.matplotlib.hist` (drop-in replacement for `plt.hist`)
16-
- **Plotly**: `khisto.plotly.histogram` (compatible with Plotly Express)
11+
- **NumPy Compatible**: Drop-in replacement for `numpy.histogram`.
12+
- **Matplotlib Integration**: `khisto.matplotlib.hist` works like `plt.hist`.
13+
- **Minimal Dependencies**: Only requires NumPy (matplotlib optional for plotting).
1714

1815
## Installation
1916

20-
### From PyPI
21-
22-
Install the core library:
23-
2417
```bash
2518
pip install khisto
2619
```
2720

28-
Install with plotting support:
21+
With matplotlib support:
2922

3023
```bash
31-
# For Matplotlib support
3224
pip install "khisto[matplotlib]"
33-
34-
# For Plotly support
35-
pip install "khisto[plotly]"
36-
37-
# For everything
38-
pip install "khisto[all]"
3925
```
4026

41-
## Usage
42-
43-
### 1. Core Array API
27+
## Quick Start
4428

45-
Compute optimal histograms and ECDFs directly from arrays.
29+
### NumPy-like API
4630

4731
```python
4832
import numpy as np
49-
from khisto.array import histogram, ecdf
33+
from khisto import histogram
5034

5135
# Generate data
5236
data = np.random.normal(0, 1, 1000)
5337

54-
# Compute optimal histogram (returns density values and bin edges)
55-
values, edges = histogram(data, granularity="best")
38+
# Compute optimal histogram (drop-in replacement for np.histogram)
39+
hist, bin_edges = histogram(data)
5640

57-
# Compute ECDF
58-
cdf = ecdf(data)
59-
print(cdf(0.0)) # Evaluate CDF at x=0
60-
```
41+
# With density normalization
42+
density, bin_edges = histogram(data, density=True)
43+
44+
# Limit maximum number of bins
45+
hist, bin_edges = histogram(data, max_bins=10)
6146

62-
### 2. Matplotlib Integration
47+
# Specify range
48+
hist, bin_edges = histogram(data, range=(-2, 2))
49+
```
6350

64-
Use Khisto as a drop-in replacement for `plt.hist`.
51+
### Matplotlib Integration
6552

6653
```python
67-
import matplotlib.pyplot as plt
68-
import khisto.matplotlib as khm
6954
import numpy as np
55+
import matplotlib.pyplot as plt
56+
from khisto.matplotlib import hist
7057

7158
data = np.random.normal(0, 1, 1000)
7259

73-
# Standard Matplotlib histogram
74-
# plt.hist(data, bins=30)
75-
76-
# Khisto optimal histogram
77-
khm.hist(data, density=True)
60+
# Create optimal histogram plot
61+
n, bins, patches = hist(data)
62+
plt.show()
7863

64+
# With density
65+
n, bins, patches = hist(data, density=True)
66+
plt.xlabel('Value')
67+
plt.ylabel('Density')
7968
plt.show()
8069
```
8170

82-
### 3. Plotly Integration
71+
## API Reference
8372

84-
Create interactive histograms with optimal binning.
73+
### `khisto.histogram`
8574

8675
```python
87-
import plotly.express as px
88-
import khisto.plotly as khp
76+
def histogram(
77+
a: ArrayLike,
78+
range: Optional[tuple[float, float]] = None,
79+
max_bins: Optional[int] = None,
80+
density: bool = False,
81+
) -> tuple[ndarray, ndarray]
82+
```
83+
84+
Compute an optimal histogram using the Khiops binning algorithm.
8985

90-
df = px.data.tips()
86+
**Parameters:**
87+
- `a`: Input data. The histogram is computed over the flattened array.
88+
- `range`: The lower and upper range of the bins. Values outside are ignored.
89+
- `max_bins`: Maximum number of bins. If None, the algorithm selects optimal.
90+
- `density`: If True, return probability density. If False, return counts.
9191

92-
# Create histogram
93-
fig = khp.histogram(df, x="total_bill", color="sex")
94-
fig.show()
92+
**Returns:**
93+
- `hist`: The values of the histogram (counts or density).
94+
- `bin_edges`: The bin edges (length = len(hist) + 1).
95+
96+
### `khisto.matplotlib.hist`
97+
98+
```python
99+
def hist(
100+
x: ArrayLike,
101+
range: Optional[tuple[float, float]] = None,
102+
max_bins: Optional[int] = None,
103+
density: bool = False,
104+
histtype: str = "bar",
105+
orientation: Literal["vertical", "horizontal"] = "vertical",
106+
log: bool = False,
107+
color: Optional[str] = None,
108+
label: Optional[str] = None,
109+
ax: Optional[Axes] = None,
110+
**kwargs,
111+
) -> tuple[ndarray, ndarray, Any]
95112
```
96113

97-
## Development
114+
Plot an optimal histogram using matplotlib.
115+
116+
**Parameters:**
117+
- `x`: Input data.
118+
- `range`: The lower and upper range of the bins.
119+
- `max_bins`: Maximum number of bins.
120+
- `density`: If True, plot probability density.
121+
- `histtype`: Type of histogram (`"bar"`, `"step"`, `"stepfilled"`).
122+
- `orientation`: `"vertical"` or `"horizontal"`.
123+
- `log`: If True, set log scale on the value axis.
124+
- `ax`: Matplotlib axes to plot on.
125+
126+
**Returns:**
127+
- `n`: The histogram values.
128+
- `bins`: The bin edges.
129+
- `patches`: The matplotlib patches.
98130

99-
This project uses [uv](https://github.com/astral-sh/uv) for dependency management and packaging.
131+
## How It Works
100132

101-
### Installation from Source
133+
Khisto uses the Khiops optimal binning algorithm based on the MODL (Minimum Optimal Description Length) principle. Instead of using fixed-width bins like traditional histograms, it:
102134

103-
1. **Install uv**:
104-
```bash
105-
curl -LsSf https://astral.sh/uv/install.sh | sh
106-
```
135+
1. Analyzes the data distribution
136+
2. Finds bin boundaries that minimize information loss
137+
3. Creates variable-width bins that adapt to data density
107138

108-
2. **Clone the repository**:
109-
```bash
110-
git clone https://github.com/yourusername/khisto-python.git
111-
cd khisto-python
112-
```
139+
This results in histograms that better represent the underlying distribution, with finer bins in dense regions and wider bins in sparse regions.
113140

114-
3. **Sync dependencies**:
115-
Create a virtual environment and install all dependencies (including dev and optional extras):
116-
```bash
117-
uv sync --all-extras
118-
```
141+
## Development
119142

120-
4. **Run Tests**:
121-
```bash
122-
uv run pytest
123-
```
143+
```bash
144+
# Clone repository
145+
git clone https://github.com/khiops/khisto-python.git
146+
cd khisto-python
124147

125-
### Project Structure
148+
# Install with dev dependencies
149+
pip install -e ".[matplotlib]"
126150

127-
- `src/khisto/array`: Core algorithms and Array API.
128-
- `src/khisto/matplotlib`: Matplotlib plotting backends.
129-
- `src/khisto/plotly`: Plotly plotting backends.
130-
- `src/khiops`: C++ backend source (requires CMake to build if modifying).
151+
# Run tests
152+
pytest
153+
```
131154

132155
## License
133156

0 commit comments

Comments
 (0)