-
Notifications
You must be signed in to change notification settings - Fork 21
lowess
Ivan Svetunkov edited this page Jan 31, 2026
·
1 revision
LOWESS (Locally Weighted Scatterplot Smoothing) is a nonparametric regression method for smoothing scatterplots. The smooth package provides a Python implementation that exactly matches R's stats::lowess function.
The Python implementation in smooth:
- Is written in C++ based on R's original C code
- Produces results identical to R's
stats::lowess - Runs significantly faster than other Python implementations
- Uses Cleveland's (1979) algorithm with tricube weighting and iterative robustification
from smooth import lowess
import numpy as np
# Generate noisy data
x = np.linspace(0, 2*np.pi, 50)
y = np.sin(x) + np.random.randn(50) * 0.3
# Apply LOWESS smoothing
result = lowess(x, y)
# Access smoothed values
x_smooth = result['x'] # Sorted x values
y_smooth = result['y'] # Smoothed y values# R's built-in lowess
result <- lowess(x, y)
result$x # Sorted x values
result$y # Smoothed y values| Parameter | Type (R) | Type (Python) | Default | Description |
|---|---|---|---|---|
x |
numeric vector | array-like | - | X values. Can be 2D array with x in first column |
y |
numeric vector | array-like | NULL/None | Y values. Optional if x is 2D array |
f |
numeric | float | 2/3 | Smoother span (fraction of points). Larger = smoother |
iter |
integer | int | 3 | Number of robustifying iterations |
delta |
numeric | float | 0.01 * range(x) | Distance threshold for interpolation |
Returns a dictionary (Python) or list (R) with two components:
| Component | Type | Description |
|---|---|---|
x |
array/vector | Sorted x values |
y |
array/vector | Smoothed y values corresponding to sorted x |
from smooth import lowess
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x) + np.random.randn(100) * 0.5
# More smoothing (larger span)
result_smooth = lowess(x, y, f=0.8)
# Less smoothing (smaller span)
result_rough = lowess(x, y, f=0.2)LOWESS is robust to outliers due to its iterative reweighting scheme:
# Add outliers to data
y_outliers = y.copy()
y_outliers[25] = 10 # Outlier
y_outliers[50] = -5 # Outlier
# Default iterations (robust)
result = lowess(x, y_outliers, iter=3)
# More iterations for heavily contaminated data
result_robust = lowess(x, y_outliers, iter=5)
# No robustification (faster but sensitive to outliers)
result_fast = lowess(x, y_outliers, iter=0)Like R, you can pass x and y as a single 2D array:
# Combine x and y into 2D array
xy = np.column_stack([x, y])
# Call with single argument
result = lowess(xy)LOWESS uses Cleveland's (1979) algorithm:
- Local Fitting: At each point, fit a weighted linear regression using nearby points. Weights decrease with distance using a tricube function:
w(u) = (1 - |u|^3)^3 \quad for |u| < 1
-
Robustness Iterations: Recompute weights based on residuals to downweight outliers. Repeat
itertimes. -
Interpolation: For efficiency, only compute fits at a subset of points (controlled by
delta) and interpolate between them.
LOWESS is used internally by other smooth functions:
-
msdecompose: Uses LOWESS for trend extraction when
smoother="lowess"(default) -
ADAM/ES: Uses LOWESS for initial state estimation when
smoother="lowess"(default). Calls msdecompose for that.
- Cleveland, W.S. (1979). Robust Locally Weighted Regression and Smoothing Scatterplots. Journal of the American Statistical Association, 74(368), 829-836. DOI: 10.1080/01621459.1979.10481038
- msdecompose - Multiple seasonal decomposition using LOWESS
- ADAM - Uses LOWESS for initialization
- Model-Estimation - Smoother options for model estimation