Visualization Module

The temporalcv.viz module provides Tufte-inspired visualizations for cross-validation, gate results, and prediction intervals. All visualizations follow Edward Tufte’s principles for data graphics.

Tufte Principles Applied

  1. Maximize data-ink ratio — Remove chartjunk, use minimal spines

  2. Direct labeling — Label data directly, minimize legends

  3. Muted colors — Avoid saturated colors that distract

  4. Small multiples — Enable comparison through consistent formatting

When to Use

        flowchart TD
    Start[Need Visualization?] --> Q1{What are you visualizing?}
    Q1 -->|CV folds| CVFoldsDisplay
    Q1 -->|Gate results| GateDisplay[GateResultDisplay or GateComparisonDisplay]
    Q1 -->|Prediction intervals| PredictionIntervalDisplay
    Q1 -->|Model metrics| MetricComparisonDisplay

    CVFoldsDisplay --> Usage1[Show train/test/gap structure]
    GateDisplay --> Usage2[Show HALT/WARN/PASS status]
    PredictionIntervalDisplay --> Usage3[Show coverage and width]
    MetricComparisonDisplay --> Usage4[Compare MAE, RMSE across models]
    

API Patterns

The module provides two API styles:

sklearn-style Display Classes

Best for complex visualizations and method chaining:

from temporalcv.viz import CVFoldsDisplay

display = CVFoldsDisplay.from_cv(cv, X, y)
display.plot(tufte=True, title="Walk-Forward CV")
fig = display.figure_  # Access matplotlib figure

statsmodels-style Functions

Best for quick one-liners:

from temporalcv.viz import plot_cv_folds

ax = plot_cv_folds(cv, X, title="Walk-Forward CV")
plt.show()

Display Classes

CVFoldsDisplay

Visualize cross-validation fold structure with train/test/gap regions.

class temporalcv.viz.CVFoldsDisplay(train_indices, test_indices, *, gap_indices=None, n_samples=None)[source]

Bases: BaseDisplay

Visualization of cross-validation fold structure.

Displays train/test splits as horizontal bars, with optional gap visualization for time series cross-validation.

Parameters:
  • train_indices (list of array-like) – Training indices for each fold.

  • test_indices (list of array-like) – Test indices for each fold.

  • gap_indices (list of array-like, optional) – Gap indices for each fold (for walk-forward CV with gap).

  • n_samples (int, optional) – Total number of samples. Inferred from indices if not provided.

ax_

The axes used for plotting.

Type:

matplotlib.axes.Axes

figure_

The figure containing the plot.

Type:

matplotlib.figure.Figure

See also

temporalcv.WalkForwardCV

Walk-forward cross-validator with gap.

temporalcv.cv_financial.PurgedKFold

Purged K-Fold for finance.

Examples

>>> from temporalcv import WalkForwardCV
>>> from temporalcv.viz import CVFoldsDisplay
>>> import numpy as np
>>>
>>> X = np.random.randn(200, 5)
>>> y = np.random.randn(200)
>>> cv = WalkForwardCV(n_splits=5, test_size=20, extra_gap=1)
>>>
>>> # From cross-validator
>>> display = CVFoldsDisplay.from_cv(cv, X, y)
>>> display.plot()
>>>
>>> # Or from pre-computed splits
>>> splits = list(cv.split(X, y))
>>> display = CVFoldsDisplay.from_splits(splits)
>>> display.plot()
__init__(train_indices, test_indices, *, gap_indices=None, n_samples=None)[source]
Parameters:
classmethod from_cv(cv, X, y=None, *, groups=None)[source]

Create display from a cross-validator object.

Parameters:
  • cv (cross-validator) – A scikit-learn compatible cross-validator with split() method.

  • X (array-like of shape (n_samples, n_features)) – Training data.

  • y (array-like of shape (n_samples,), optional) – Target values.

  • groups (array-like of shape (n_samples,), optional) – Group labels for GroupKFold-like splitters.

Returns:

The display object.

Return type:

CVFoldsDisplay

Examples

>>> from temporalcv import WalkForwardCV
>>> cv = WalkForwardCV(n_splits=5, test_size=20)
>>> display = CVFoldsDisplay.from_cv(cv, X, y)
classmethod from_splits(splits, *, n_samples=None)[source]

Create display from pre-computed splits.

Parameters:
  • splits (list of (train_indices, test_indices) tuples) – Pre-computed splits from cv.split().

  • n_samples (int, optional) – Total number of samples.

Returns:

The display object.

Return type:

CVFoldsDisplay

Examples

>>> splits = list(cv.split(X, y))
>>> display = CVFoldsDisplay.from_splits(splits, n_samples=len(X))
plot(*, ax=None, tufte=True, bar_height=0.6, show_labels=True, title=None)[source]

Plot the cross-validation fold structure.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • bar_height (float) – Height of each fold bar (0-1).

  • show_labels (bool) – If True, show fold labels and sample counts.

  • title (str, optional) – Plot title. If None, uses default.

Returns:

The display object for method chaining.

Return type:

self

Examples

>>> display.plot(title="Walk-Forward CV Folds")
>>> plt.tight_layout()
>>> plt.show()

Example:

from temporalcv import WalkForwardCV
from temporalcv.viz import CVFoldsDisplay

cv = WalkForwardCV(n_splits=5, test_size=20, extra_gap=5)
display = CVFoldsDisplay.from_cv(cv, X, y)
display.plot(title="Walk-Forward with Gap")

GateResultDisplay

Visualize a single validation gate result (HALT/WARN/PASS).

class temporalcv.viz.GateResultDisplay(name, status, message, *, metrics=None)[source]

Bases: BaseDisplay

Visualization of a single gate result.

Displays the gate status (HALT/WARN/PASS) with metric details.

Parameters:
  • name (str) – Gate name.

  • status (str) – Gate status (“HALT”, “WARN”, or “PASS”).

  • message (str) – Gate message.

  • metrics (dict, optional) – Additional metrics to display.

ax_

The axes used for plotting.

Type:

matplotlib.axes.Axes

figure_

The figure containing the plot.

Type:

matplotlib.figure.Figure

See also

temporalcv.gates.gate_signal_verification

Signal verification gate.

temporalcv.gates.gate_suspicious_improvement

Improvement gate.

Examples

>>> from temporalcv.gates import gate_signal_verification
>>> from temporalcv.viz import GateResultDisplay
>>>
>>> result = gate_signal_verification(model, X, y, n_shuffles=100)
>>> display = GateResultDisplay.from_gate(result)
>>> display.plot()
__init__(name, status, message, *, metrics=None)[source]
Parameters:
classmethod from_gate(gate_result)[source]

Create display from a GateResult object.

Parameters:

gate_result (GateResult) – Result from a gate function (e.g., gate_signal_verification).

Returns:

The display object.

Return type:

GateResultDisplay

Examples

>>> result = gate_signal_verification(model, X, y)
>>> display = GateResultDisplay.from_gate(result)
plot(*, ax=None, tufte=True, show_message=True)[source]

Plot the gate result.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • show_message (bool) – If True, show the gate message.

Returns:

The display object for method chaining.

Return type:

self

Example:

from temporalcv.gates import gate_signal_verification
from temporalcv.viz import GateResultDisplay

result = gate_signal_verification(model, X, y, n_shuffles=100)
display = GateResultDisplay.from_gate(result)
display.plot()

GateComparisonDisplay

Compare multiple gate results side by side.

class temporalcv.viz.GateComparisonDisplay(names, statuses, messages=None)[source]

Bases: BaseDisplay

Visualization comparing multiple gate results.

Displays multiple gates side by side for a comprehensive view.

Parameters:
  • gate_results (list) – List of GateResult objects or (name, status) tuples.

  • names (list[str])

  • statuses (list[str])

  • messages (list[str] | None)

ax_

The axes used for plotting.

Type:

matplotlib.axes.Axes

figure_

The figure containing the plot.

Type:

matplotlib.figure.Figure

See also

temporalcv.gates.run_gates

Run multiple gates.

GateResultDisplay

Single gate visualization.

Examples

>>> from temporalcv.gates import run_gates, gate_signal_verification
>>> from temporalcv.viz import GateComparisonDisplay
>>>
>>> gates = [
...     gate_signal_verification(model, X, y),
...     gate_suspicious_improvement(model_mae, baseline_mae),
... ]
>>> report = run_gates(gates)
>>> display = GateComparisonDisplay.from_report(report)
>>> display.plot()
Parameters:
__init__(names, statuses, messages=None)[source]
Parameters:
classmethod from_gates(gate_results)[source]

Create display from a list of GateResult objects.

Parameters:

gate_results (list of GateResult) – Results from gate functions.

Returns:

The display object.

Return type:

GateComparisonDisplay

classmethod from_report(report)[source]

Create display from a GateReport object.

Parameters:

report (GateReport) – Report from run_gates().

Returns:

The display object.

Return type:

GateComparisonDisplay

plot(*, ax=None, tufte=True, orientation='horizontal', show_messages=False, title=None)[source]

Plot the gate comparison.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • orientation (str) – “horizontal” (bars left-right) or “vertical” (bars top-bottom).

  • show_messages (bool) – If True, show gate messages.

  • title (str, optional) – Plot title.

Returns:

The display object for method chaining.

Return type:

self

Example:

from temporalcv.gates import run_gates
from temporalcv.viz import GateComparisonDisplay

report = run_gates([gate1, gate2, gate3])
display = GateComparisonDisplay.from_report(report)
display.plot(orientation="horizontal")

PredictionIntervalDisplay

Visualize prediction intervals with coverage highlighting.

class temporalcv.viz.PredictionIntervalDisplay(predictions, lower, upper, *, actuals=None, confidence=0.9, x=None)[source]

Bases: BaseDisplay

Visualization of prediction intervals with actuals.

Displays prediction intervals as a shaded region with actual values overlaid, highlighting coverage.

Parameters:
  • predictions (array-like) – Point predictions.

  • lower (array-like) – Lower bounds of intervals.

  • upper (array-like) – Upper bounds of intervals.

  • actuals (array-like, optional) – Actual values for coverage visualization.

  • confidence (float) – Confidence level (e.g., 0.90 for 90% intervals).

  • x (np.ndarray | None)

ax_

The axes used for plotting.

Type:

matplotlib.axes.Axes

figure_

The figure containing the plot.

Type:

matplotlib.figure.Figure

coverage_

Empirical coverage if actuals provided, None otherwise.

Type:

float or None

See also

temporalcv.conformal.SplitConformalPredictor

Split conformal.

temporalcv.conformal.AdaptiveConformalPredictor

Adaptive conformal.

Examples

>>> from temporalcv.conformal import SplitConformalPredictor
>>> from temporalcv.viz import PredictionIntervalDisplay
>>>
>>> conformal = SplitConformalPredictor(alpha=0.10)
>>> conformal.calibrate(cal_preds, cal_actuals)
>>> intervals = conformal.predict_interval(test_preds)
>>>
>>> display = PredictionIntervalDisplay.from_conformal(intervals, test_actuals)
>>> display.plot()
Parameters:
  • x (ndarray | None)

  • predictions (np.ndarray)

  • lower (np.ndarray)

  • upper (np.ndarray)

  • actuals (np.ndarray | None)

  • confidence (float)

__init__(predictions, lower, upper, *, actuals=None, confidence=0.9, x=None)[source]
Parameters:
classmethod from_conformal(intervals, actuals=None, *, x=None)[source]

Create display from a PredictionInterval object.

Parameters:
  • intervals (PredictionInterval) – Prediction interval object from conformal predictor.

  • actuals (array-like, optional) – Actual values for coverage visualization.

  • x (array-like, optional) – X-axis values (e.g., time indices).

Returns:

The display object.

Return type:

PredictionIntervalDisplay

Examples

>>> intervals = conformal.predict_interval(test_preds)
>>> display = PredictionIntervalDisplay.from_conformal(intervals, test_actuals)
classmethod from_predictions(predictions, lower, upper, *, actuals=None, confidence=0.9, x=None)[source]

Create display from arrays.

Parameters:
  • predictions (array-like) – Point predictions.

  • lower (array-like) – Lower bounds.

  • upper (array-like) – Upper bounds.

  • actuals (array-like, optional) – Actual values.

  • confidence (float) – Confidence level.

  • x (array-like, optional) – X-axis values.

Returns:

The display object.

Return type:

PredictionIntervalDisplay

plot(*, ax=None, tufte=True, show_predictions=True, show_actuals=True, show_coverage=True, title=None)[source]

Plot the prediction intervals.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • show_predictions (bool) – If True, show point predictions as line.

  • show_actuals (bool) – If True, show actual values.

  • show_coverage (bool) – If True, highlight covered/uncovered points.

  • title (str, optional) – Plot title.

Returns:

The display object for method chaining.

Return type:

self

plot_width(*, ax=None, tufte=True, title=None)[source]

Plot the interval widths over time.

Useful for adaptive conformal where width varies.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on.

  • tufte (bool) – If True, apply Tufte styling.

  • title (str, optional) – Plot title.

Returns:

The display object.

Return type:

self

Example:

from temporalcv.conformal import SplitConformalPredictor
from temporalcv.viz import PredictionIntervalDisplay

conformal = SplitConformalPredictor(alpha=0.10)
conformal.calibrate(cal_preds, cal_actuals)
intervals = conformal.predict_interval(test_preds)

display = PredictionIntervalDisplay.from_conformal(intervals, test_actuals)
display.plot(show_coverage=True)
display.plot_width()  # Show interval width variation

MetricComparisonDisplay

Compare metrics across multiple models.

class temporalcv.viz.MetricComparisonDisplay(model_names, metric_names, values, *, lower_is_better=None, baseline_idx=None)[source]

Bases: BaseDisplay

Visualization comparing metrics across models.

Displays metric comparisons as grouped bar charts with Tufte styling.

Parameters:
  • model_names (list of str) – Names of models being compared.

  • metric_names (list of str) – Names of metrics being compared.

  • values (array-like of shape (n_models, n_metrics)) – Metric values for each model.

  • lower_is_better (dict, optional) – Map of metric name to bool indicating if lower is better. Default: True for all metrics.

  • baseline_idx (int | None)

ax_

The axes used for plotting.

Type:

matplotlib.axes.Axes

figure_

The figure containing the plot.

Type:

matplotlib.figure.Figure

See also

temporalcv.compare.compare_horizons

Compare across horizons.

temporalcv.compare.compare_models

Compare model performance.

Examples

>>> from temporalcv.viz import MetricComparisonDisplay
>>>
>>> # From dictionary
>>> results = {"Model A": {"MAE": 0.15}, "Model B": {"MAE": 0.12}}
>>> display = MetricComparisonDisplay.from_dict(results)
>>> display.plot()
>>>
>>> # From arrays
>>> display = MetricComparisonDisplay.from_arrays(
...     model_names=["A", "B"],
...     metric_names=["MAE", "RMSE"],
...     values=[[0.15, 0.22], [0.12, 0.19]],
... )
>>> display.plot()
Parameters:
__init__(model_names, metric_names, values, *, lower_is_better=None, baseline_idx=None)[source]
Parameters:
classmethod from_dict(results, *, lower_is_better=None, baseline=None)[source]

Create display from a nested dictionary.

Parameters:
  • results (dict) – Nested dict of {model_name: {metric_name: value}}.

  • lower_is_better (dict, optional) – Map of metric name to bool.

  • baseline (str, optional) – Name of baseline model for relative comparison.

Returns:

The display object.

Return type:

MetricComparisonDisplay

Examples

>>> results = {
...     "Baseline": {"MAE": 0.20, "RMSE": 0.28},
...     "Model A": {"MAE": 0.15, "RMSE": 0.22},
... }
>>> display = MetricComparisonDisplay.from_dict(results, baseline="Baseline")
classmethod from_arrays(model_names, metric_names, values, *, lower_is_better=None, baseline_idx=None)[source]

Create display from arrays.

Parameters:
  • model_names (list of str) – Names of models.

  • metric_names (list of str) – Names of metrics.

  • values (array-like of shape (n_models, n_metrics)) – Metric values.

  • lower_is_better (dict, optional) – Map of metric name to bool.

  • baseline_idx (int, optional) – Index of baseline model.

Returns:

The display object.

Return type:

MetricComparisonDisplay

plot(*, ax=None, tufte=True, orientation='vertical', show_values=True, show_best=True, title=None, metric_idx=None)[source]

Plot the metric comparison.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • orientation (str) – “vertical” (bars go up) or “horizontal” (bars go right).

  • show_values (bool) – If True, show metric values on bars.

  • show_best (bool) – If True, highlight best model for each metric.

  • title (str, optional) – Plot title.

  • metric_idx (int, optional) – If provided, plot only this metric (useful for single-metric comparison).

Returns:

The display object for method chaining.

Return type:

self

plot_relative(*, ax=None, tufte=True, title=None)[source]

Plot metrics relative to baseline (percent improvement).

Requires baseline_idx to be set.

Parameters:
  • ax (matplotlib.axes.Axes, optional) – Axes to plot on.

  • tufte (bool) – If True, apply Tufte styling.

  • title (str, optional) – Plot title.

Returns:

The display object.

Return type:

self

Example:

from temporalcv.viz import MetricComparisonDisplay

results = {
    "Baseline": {"MAE": 0.20, "RMSE": 0.28},
    "Model A": {"MAE": 0.15, "RMSE": 0.22},
    "Model B": {"MAE": 0.12, "RMSE": 0.19},
}

display = MetricComparisonDisplay.from_dict(results, baseline="Baseline")
display.plot(show_best=True)  # Highlights best model per metric
display.plot_relative()  # Shows % improvement vs baseline

Functions

plot_cv_folds

temporalcv.viz.plot_cv_folds(cv, X, y=None, *, groups=None, ax=None, tufte=True, title=None)[source]

Plot cross-validation fold structure.

Convenience function wrapping CVFoldsDisplay.

Parameters:
  • cv (cross-validator) – A scikit-learn compatible cross-validator.

  • X (array-like) – Training data.

  • y (array-like, optional) – Target values.

  • groups (array-like, optional) – Group labels.

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • title (str, optional) – Plot title.

Returns:

The axes with the plot.

Return type:

matplotlib.axes.Axes

Examples

>>> from temporalcv import WalkForwardCV
>>> from temporalcv.viz import plot_cv_folds
>>>
>>> cv = WalkForwardCV(n_splits=5, test_size=20)
>>> plot_cv_folds(cv, X, title="Walk-Forward CV")
>>> plt.show()

See also

CVFoldsDisplay

Class-based API for more customization.

plot_gate_result

temporalcv.viz.plot_gate_result(gate_result, *, ax=None, tufte=True, show_message=True)[source]

Plot a single gate result.

Displays the gate status (HALT/WARN/PASS) with message.

Parameters:
  • gate_result (GateResult) – Result from a gate function.

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates new figure.

  • tufte (bool) – If True, apply Tufte styling (default).

  • show_message (bool) – If True, show the gate message.

Returns:

The axes with the plot.

Return type:

matplotlib.axes.Axes

Examples

>>> from temporalcv.gates import gate_signal_verification
>>> from temporalcv.viz import plot_gate_result
>>>
>>> result = gate_signal_verification(model, X, y, n_shuffles=100)
>>> plot_gate_result(result)
>>> plt.show()

See also

GateResultDisplay

Class-based API.

plot_gate_comparison

Compare multiple gates.

plot_gate_comparison

temporalcv.viz.plot_gate_comparison(gate_results, *, ax=None, tufte=True, orientation='horizontal', title=None)[source]

Plot comparison of multiple gate results.

Displays multiple gates side by side for a comprehensive view.

Parameters:
  • gate_results (list of GateResult or GateReport) – Results from gate functions or a GateReport from run_gates().

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on.

  • tufte (bool) – If True, apply Tufte styling.

  • orientation (str) – “horizontal” (bars left-right) or “vertical” (bars top-bottom).

  • title (str, optional) – Plot title.

Returns:

The axes with the plot.

Return type:

matplotlib.axes.Axes

Examples

>>> from temporalcv.gates import run_gates, gate_signal_verification
>>> from temporalcv.viz import plot_gate_comparison
>>>
>>> gates = [
...     gate_signal_verification(model, X, y),
...     gate_suspicious_improvement(model_mae, baseline_mae),
... ]
>>> report = run_gates(gates)
>>> plot_gate_comparison(report, title="Validation Gates")
>>> plt.show()

See also

GateComparisonDisplay

Class-based API.

plot_gate_result

Single gate visualization.

plot_prediction_intervals

temporalcv.viz.plot_prediction_intervals(intervals, actuals=None, *, x=None, ax=None, tufte=True, show_coverage=True, title=None)[source]

Plot prediction intervals with actuals.

Convenience function wrapping PredictionIntervalDisplay.

Parameters:
  • intervals (PredictionInterval) – Prediction interval object from conformal predictor.

  • actuals (array-like, optional) – Actual values for coverage visualization.

  • x (array-like, optional) – X-axis values (e.g., time indices).

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on.

  • tufte (bool) – If True, apply Tufte styling.

  • show_coverage (bool) – If True, highlight covered/uncovered points.

  • title (str, optional) – Plot title.

Returns:

The axes with the plot.

Return type:

matplotlib.axes.Axes

Examples

>>> from temporalcv.conformal import SplitConformalPredictor
>>> from temporalcv.viz import plot_prediction_intervals
>>>
>>> conformal = SplitConformalPredictor(alpha=0.10)
>>> conformal.calibrate(cal_preds, cal_actuals)
>>> intervals = conformal.predict_interval(test_preds)
>>>
>>> plot_prediction_intervals(intervals, test_actuals)
>>> plt.show()

See also

PredictionIntervalDisplay

Class-based API.

plot_interval_width

temporalcv.viz.plot_interval_width(intervals, *, x=None, ax=None, tufte=True, title=None)[source]

Plot prediction interval widths over time.

Useful for adaptive conformal where width varies.

Parameters:
  • intervals (PredictionInterval) – Prediction interval object.

  • x (array-like, optional) – X-axis values.

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on.

  • tufte (bool) – If True, apply Tufte styling.

  • title (str, optional) – Plot title.

Returns:

The axes with the plot.

Return type:

matplotlib.axes.Axes

Examples

>>> from temporalcv.conformal import AdaptiveConformalPredictor
>>> from temporalcv.viz import plot_interval_width
>>>
>>> adaptive = AdaptiveConformalPredictor(alpha=0.10, gamma=0.01)
>>> # ... fit and predict ...
>>> plot_interval_width(intervals)
>>> plt.show()

See also

PredictionIntervalDisplay.plot_width

Class-based method.

plot_metric_comparison

temporalcv.viz.plot_metric_comparison(results, *, ax=None, tufte=True, baseline=None, show_values=True, title=None)[source]

Plot metric comparison across models.

Parameters:
  • results (dict) – Nested dict of {model_name: {metric_name: value}}.

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on.

  • tufte (bool) – If True, apply Tufte styling.

  • baseline (str, optional) – Name of baseline model for highlighting.

  • show_values (bool) – If True, show values on bars.

  • title (str, optional) – Plot title.

Returns:

The axes with the plot.

Return type:

matplotlib.axes.Axes

Examples

>>> from temporalcv.viz import plot_metric_comparison
>>>
>>> results = {
...     "Model A": {"MAE": 0.15, "RMSE": 0.22},
...     "Model B": {"MAE": 0.12, "RMSE": 0.19},
... }
>>> plot_metric_comparison(results, baseline="Model A")
>>> plt.show()

See also

MetricComparisonDisplay

Class-based API.


Styling Primitives

For custom visualizations, use the low-level styling functions:

apply_tufte_style

Apply Tufte’s principles to any matplotlib axes:

from temporalcv.viz import apply_tufte_style

fig, ax = plt.subplots()
ax.plot(x, y)
apply_tufte_style(ax)  # Removes top/right spines, subtle colors
temporalcv.viz.apply_tufte_style(ax)[source]

Apply Tufte’s principles to a matplotlib axes.

Implements: - Remove top and right spines (maximize data-ink) - Subtle spine colors - Remove grid (or make very subtle) - Refined tick styling

Parameters:

ax (matplotlib.axes.Axes) – The axes to style.

Returns:

The styled axes (for chaining).

Return type:

matplotlib.axes.Axes

Examples

>>> fig, ax = plt.subplots()
>>> ax.plot([1, 2, 3], [1, 4, 2])
>>> apply_tufte_style(ax)
>>> plt.show()

direct_label

Label data points directly (eliminates legends):

from temporalcv.viz import direct_label

ax.plot(x, y)
direct_label(ax, x[-1], y[-1], "Series A", offset=(5, 0))
temporalcv.viz.direct_label(ax, x, y, text, offset=(5, 5), **kwargs)[source]

Add a direct label to a data point (Tufte principle: label on the data).

Direct labeling eliminates the need for legends, improving data-ink ratio.

Parameters:
  • ax (matplotlib.axes.Axes) – The axes to annotate.

  • x (float) – X coordinate of the data point.

  • y (float) – Y coordinate of the data point.

  • text (str) – Label text.

  • offset (tuple of float) – Offset in points (x, y) from the data point.

  • **kwargs (Any) – Additional arguments passed to ax.annotate().

Return type:

None

Examples

>>> fig, ax = plt.subplots()
>>> ax.plot([1, 2, 3], [1, 4, 2])
>>> direct_label(ax, 2, 4, "Peak", offset=(5, 5))

create_tufte_figure

Create a figure with Tufte styling pre-applied:

from temporalcv.viz import create_tufte_figure

fig, axes = create_tufte_figure(nrows=2, ncols=2)
# All axes already have Tufte styling
temporalcv.viz.create_tufte_figure(nrows=1, ncols=1, figsize=None, **kwargs)[source]

Create a figure with Tufte styling applied.

Parameters:
  • nrows (int) – Number of rows.

  • ncols (int) – Number of columns.

  • figsize (tuple of float, optional) – Figure size (width, height) in inches.

  • **kwargs (Any) – Additional arguments passed to plt.subplots().

Return type:

tuple[Figure, Axes | ndarray]

Returns:

  • fig (matplotlib.figure.Figure) – The figure.

  • axes (matplotlib.axes.Axes or array of Axes) – The axes, with Tufte styling applied.

Color Palettes

from temporalcv.viz import TUFTE_PALETTE, COLORS

# TUFTE_PALETTE: primary, secondary, accent, success, warning, etc.
# COLORS: train, test, gap, pass, warn, halt, prediction, actual

Common Patterns

Subplot Layout

from temporalcv.viz import (
    CVFoldsDisplay,
    GateComparisonDisplay,
    create_tufte_figure,
)

fig, (ax1, ax2) = create_tufte_figure(nrows=1, ncols=2, figsize=(12, 4))

CVFoldsDisplay.from_cv(cv, X).plot(ax=ax1, title="CV Structure")
GateComparisonDisplay.from_report(report).plot(ax=ax2, title="Gates")

plt.tight_layout()

Saving Figures

display = CVFoldsDisplay.from_cv(cv, X)
display.plot()

# High-quality PNG for reports
display.figure_.savefig("cv_folds.png", dpi=300, bbox_inches="tight")

# Vector format for publication
display.figure_.savefig("cv_folds.svg", format="svg", bbox_inches="tight")

Disabling Tufte Style

If you prefer matplotlib defaults:

display.plot(tufte=False)  # Use default matplotlib styling

See Also

References