regression
Pairwise data · used in the anscombe cookbook recipe
Minimal call
import random
rng = random.Random(11)
xs = [i * 0.5 for i in range(30)]
df = {"x": xs, "y": [1 + 0.7 * x + rng.gauss(0, 1) for x in xs]}
c = pt.chart(df, aes(x="x", y="y"), xlabel="x", ylabel="y")
c.add_scatter(size=2.5)
c.add_regression()
Docstring
OLS fit line plus Student-t confidence ribbon.
Fits y ~ x by closed-form OLS, draws the fit line, and shades a confidence
band using the exact Student-t critical value at n - 2 degrees of freedom.
The scatter is not drawn here — overlay your own
`c.add_scatter(aes(x="col_x", y="col_y"))`.
c.add_regression(aes(x="col_x", y="col_y")) # columns via aes
c.add_regression(aes(x=..., y=..., color="group")) # one fit per group
c.add_regression(aes(x=..., y=...), order=2) # polynomial
c.add_regression(aes(x=..., y=...), robust=True) # Huber IRLS
c.add_regression(aes(x=..., y=...), lowess=True) # LOWESS smoother
Styling kwargs:
color= bare → literal line color; aes(color="col") → one fit
per level
palette= maps levels → colors when color is mapped in aes
order=1 polynomial degree of the fit (seaborn regplot order=);
the band generalizes to t_{α/2, n-p} with the full
covariance term se(ŷ) = σ·sqrt(xᵀ(XᵀX)⁻¹x)
robust=False True → Huber-weighted IRLS fit that downweights
outliers (seaborn regplot robust=). No analytic band
exists, so the ribbon comes from a percentile bootstrap
(n_boot=200, seed=0 — deterministic)
lowess=False True → LOWESS local-linear smoother (seaborn regplot
lowess=, ggplot geom_smooth method="loess"). Draws the
smoothed line only — like seaborn, no confidence band.
Incompatible with order=/robust=.
frac=2/3 LOWESS window: fraction of points in each local fit
(statsmodels frac=; ggplot calls it span=)
it=3 LOWESS robustifying iterations (bisquare-downweight
outliers, statsmodels it=); 0 = plain single pass
level=0.95 confidence level for the band
n_grid=80 grid resolution for evaluating the band
n_boot=200 bootstrap resamples for the robust band
seed=0 RNG seed for the robust bootstrap
alpha=0.2 ribbon fill opacity
linewidth=1.8 fit line stroke width
label=None legend label (single-fit only — multi-group auto-labels)
Math (order=1, robust=False — the closed-form fast path):
slope b = Σ((x - x̄)(y - ȳ)) / Σ((x - x̄)²)
intercept a = ȳ - b·x̄
residual σ² = SSE / (n - 2)
se(ŷ(x)) = σ · sqrt(1/n + (x - x̄)² / Σ(x - x̄)²)
t · se for the band, t = t_{α/2, n-2}
Polynomial/robust fits solve the normal equations on centered x
(conditioning); Huber uses c=1.345 with MAD scale, IRLS to convergence.
LOWESS is Cleveland's classic: per evaluation point, a degree-1 fit over
the `frac`-nearest neighbours with tricube distance weights, then `it`
rounds of bisquare residual downweighting. O(n·frac) work per point —
for very large n, lower `frac` or subsample first.