Knee-point detection in Python
kneed is a Python library (current version 0.8.6) for detecting knee (also known as elbow) points in curves. It implements the Kneedle algorithm to identify the point of maximum curvature in a given set of x and y values. The library is actively maintained with regular patch releases and occasional feature updates.
Warnings
- breaking Matplotlib became an optional dependency in v0.8.0. Code calling plotting methods (e.g., `plot_knee()`, `plot_knee_normalized()`) will now raise a `ModuleNotFoundError` if Matplotlib is not installed via `pip install kneed[plot]`.
- breaking The `scikit-learn` dependency was removed in v0.7.0. While `kneed` itself does not directly rely on `scikit-learn` for its core algorithm, code that implicitly expected `scikit-learn` to be installed alongside `kneed` (e.g., for K-Means clustering examples) might now fail.
- breaking As of v0.7.0, `kneed` validates the `curve` and `direction` arguments. Providing invalid string values for these parameters will now result in an error, whereas they might have been silently ignored or led to incorrect behavior in previous versions.
- gotcha Beginning with v0.8.4 and further refined in v0.8.5, `kneed` no longer emits warnings when no knee/elbow point is found. Users who previously relied on parsing these warnings for error handling or informational purposes should update their logic.
- gotcha The `curve` and `direction` parameters are critical for accurate knee detection. An incorrect choice (e.g., `curve='concave'` for a convex elbow, or `direction='increasing'` for a decreasing curve) will lead to incorrect or no knee detection.
- gotcha The sensitivity parameter `S` (default `1.0`) greatly influences knee detection. Smaller `S` values detect knees more aggressively/earlier, while larger values are more conservative. Improper `S` can lead to missing a knee or identifying a false one, especially with noisy data.
Install
-
pip install kneed -
pip install kneed[plot]
Imports
- KneeLocator
from kneed import KneeLocator
- DataGenerator
from kneed import DataGenerator
- find_shape
from kneed import find_shape
Quickstart
import numpy as np
from kneed import KneeLocator, find_shape
# Example 1: Basic usage with known curve type and direction
x = np.arange(1, 11)
y = np.array([1, 2, 3, 4, 5, 5.5, 5.6, 5.7, 5.8, 5.9])
kl = KneeLocator(x, y, curve="concave", direction="increasing")
print(f"Knee at x: {kl.knee}")
print(f"Corresponding y: {kl.knee_y}")
# Example 2: Using find_shape for auto-detection
x_auto = np.arange(1, 101)
y_auto = np.sin(x_auto / 10) + np.log(x_auto) + np.random.rand(100)
auto_direction, auto_curve = find_shape(x_auto, y_auto)
kl_auto = KneeLocator(x_auto, y_auto, curve=auto_curve, direction=auto_direction)
print(f"\nAuto-detected curve: {auto_curve}, direction: {auto_direction}")
print(f"Knee at x (auto-detected): {kl_auto.knee}")