elbow_helper.plotting module

Diagnostic figure for a robust_knee() run.

Renders a self-contained SVG — no matplotlib, no Vega, no runtime image library — so this stays a core feature (no [plot] extra to install) rather than a lazy opt-in. The SVG-writing code below (the Catmull-Rom spline helper, the responsive <svg> header, the additive dark-mode block) is adapted from this project’s sibling sprezzature-figures package (scripts/make_elbow.py / _svg.py / _style.py) and copy-pasted in rather than taken as a dependency, then cut down and re-specialised for this module’s own data shapes (normalized x/y arrays and the ClearKnee / NoClearKnee result types) — elbow-helper’s only runtime dependencies stay numpy and os-helper.

The figure never shows a bare point estimate: the knee is paired with its 90% bootstrap interval and the supporting evidence (detection probability, null-model p-value, slope contrast, a BIC-derived posterior model probability, and a worst-case-normalized fit-quality score) in a compact legend. When the evidence is too weak, the figure says so plainly — a greyed, dashed curve and a reason — instead of drawing a marker that implies more confidence than the data supports.

Author

Warith Harchaoui, <warith.harchaoui@deraison.ai>

elbow_helper.plotting.plot_diagnostics(x, y=None, *, curve=None, direction=None, config=None, out=None, language='en', raw_axis=False, log_y=False, x_label=None, y_label=None)[source]

Render the robust-knee diagnostic SVG and optionally save it.

Parameters:
  • x (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knee().

  • y (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knee().

  • curve (str, optional) – Orientation; inferred from the data when omitted.

  • direction (str, optional) – Orientation; inferred from the data when omitted.

  • config (RobustKneeConfig, optional) – Thresholds and replicate counts forwarded to the pipeline.

  • out (str, optional) – If given, save the SVG to this path (parent directories are created).

  • language (str, optional) – Chrome-text language, "en" (default) or "fr".

  • raw_axis (bool, optional) – Display in original data units instead of the pipeline’s internal normalized [0, 1] square; see render_svg().

  • log_y (bool, optional) – Log-scale the y-axis (only meaningful with raw_axis=True).

  • x_label (str, optional) – Axis captions to use with raw_axis=True.

  • y_label (str, optional) – Axis captions to use with raw_axis=True.

Returns:

The complete SVG document (also written to out when given).

Return type:

str

Examples

>>> import numpy as np
>>> x = np.linspace(0, 1, 50)
>>> y = np.where(x <= 0.3, 3 * x, 0.9 + 0.1 * (x - 0.3))
>>> svg = plot_diagnostics(x, y)
>>> svg.startswith("<svg")
True
elbow_helper.plotting.plot_diagnostics_panels(svgs, *, out=None, gap=24.0)[source]

Render render_svg_panels() and optionally save it.

Parameters:
  • svgs (sequence of str) – One complete, standalone SVG document string per panel; see render_svg_panels().

  • out (str, optional) – If given, save the SVG to this path (parent directories are created).

  • gap (float, optional) – Horizontal gap, in pixels, between panels.

Returns:

The complete SVG document (also written to out when given).

Return type:

str

elbow_helper.plotting.plot_multi_diagnostics(x, y=None, *, config=None, out=None, language='en', x_label=None, y_label=None)[source]

Render the robust-knees (plural) diagnostic SVG and optionally save it.

Parameters:
  • x (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knees().

  • y (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knees().

  • config (RobustKneesConfig, optional) – Search size and false-positive-control settings.

  • out (str, optional) – If given, save the SVG to this path (parent directories are created).

  • language (str, optional) – Chrome-text language, "en" (default) or "fr".

  • x_label (str, optional) – Axis captions; default to the generic normalized-style captions when omitted.

  • y_label (str, optional) – Axis captions; default to the generic normalized-style captions when omitted.

Returns:

The complete SVG document (also written to out when given).

Return type:

str

Examples

>>> import numpy as np
>>> x = np.linspace(0, 1, 150)
>>> y = np.piecewise(
...     x, [x < 0.4, x >= 0.4], [lambda t: 2 * t, lambda t: 0.8 + 0.1 * (t - 0.4)]
... )
>>> svg = plot_multi_diagnostics(x, y)
>>> svg.startswith("<svg")
True
elbow_helper.plotting.render_svg(x, y=None, *, curve=None, direction=None, config=None, language='en', raw_axis=False, log_y=False, x_label=None, y_label=None)[source]

Build the robust-knee diagnostic as a complete, standalone SVG string.

Parameters:
  • x (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knee().

  • y (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knee().

  • curve (str, optional) – Orientation; inferred from the data when omitted.

  • direction (str, optional) – Orientation; inferred from the data when omitted.

  • config (RobustKneeConfig, optional) – Thresholds and replicate counts forwarded to the pipeline.

  • language (str, optional) – Chrome-text language, "en" (default) or "fr".

  • raw_axis (bool, optional) – Display the curve in its original data units instead of the pipeline’s internal normalized [0, 1] square. The knee marker and confidence band still come straight from result.knee_x / result.ci90, already in data units; only the displayed points and smoothed curve are mapped back through prepared’s stored x_lo/x_hi/y_lo/y_hi bounds. Default False (the package’s own normalized diagnostic view, unchanged).

  • log_y (bool, optional) – Log-scale the y-axis. Only meaningful with raw_axis=True and a strictly positive y; ignored otherwise.

  • x_label (str, optional) – Axis captions to use with raw_axis=True, where the default “x (normalized)” / “y (scaled)” captions no longer apply. Ignored when raw_axis is False.

  • y_label (str, optional) – Axis captions to use with raw_axis=True, where the default “x (normalized)” / “y (scaled)” captions no longer apply. Ignored when raw_axis is False.

Returns:

A complete SVG document: the curve with its knee (or an honest abstention state) and the evidence that backs it.

Return type:

str

elbow_helper.plotting.render_svg_multi(x, y=None, *, config=None, language='en', x_label=None, y_label=None)[source]

Build the robust-knees (plural) diagnostic as a standalone SVG string.

Unlike render_svg(), this wraps elbow_helper.robust_knees() and marks zero or more breakpoints with dashed lines rather than a single knee with a confidence band: there is no continuous broken-line fit or BIC-derived evidence legend here, only the breakpoint locations elbow_helper.robust_knees() itself reports, each an independent (discontinuous) segment boundary rather than ClearKnee’s continuous broken-line model.

Parameters:
  • x (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knees().

  • y (array-like) – The curve. y may be omitted, as in elbow_helper.robust_knees().

  • config (RobustKneesConfig, optional) – Search size and false-positive-control settings.

  • language (str, optional) – Chrome-text language, "en" (default) or "fr".

  • x_label (str, optional) – Axis captions; default to the generic normalized-style captions when omitted.

  • y_label (str, optional) – Axis captions; default to the generic normalized-style captions when omitted.

Returns:

A complete SVG document: the curve with every detected breakpoint marked by a dashed line (or an honest abstention state).

Return type:

str

elbow_helper.plotting.render_svg_panels(svgs, *, gap=24.0)[source]

Lay out several already-rendered diagnostic SVGs side by side.

Each panel is whatever complete, standalone SVG the caller already produced, typically one render_svg() call per noise level or scenario (or a mix of render_svg() / render_svg_multi() outputs), run and rendered independently: its own pipeline call, its own title/subtitle, its own legend or abstention card. This only nests those SVGs into one shared canvas via SVG’s native nested-viewport element, left to right. Useful for a controlled side-by-side comparison, such as the same shape at two noise levels.

Parameters:
  • svgs (sequence of str) – One complete, standalone SVG document string per panel.

  • gap (float, optional) – Horizontal gap, in pixels, between panels.

Returns:

A complete SVG document containing one nested panel per input SVG.

Return type:

str

Examples

>>> import numpy as np
>>> x = np.linspace(0, 1, 60)
>>> y = np.where(x < 0.5, 0.8 * x, 0.4 + 0.2 * (x - 0.5))
>>> left = render_svg(x, y + 0.01)
>>> right = render_svg(x, y + 0.2)
>>> svg = render_svg_panels([left, right])
>>> svg.count("<svg") == 3
True