plots.outlier_plots

plots.outlier_plots

Functions

Name Description
plot_outlier_flags Line plot of a series with its outlier-flagged slots marked.
visualize_outliers_hist Visualize outliers in DataFrame using stacked histograms.
visualize_outliers_plotly_scatter Visualize outliers in time series using Plotly scatter plots.

plot_outlier_flags

plots.outlier_plots.plot_outlier_flags(
    data,
    data_original,
    column,
    *,
    line_color=None,
    marker_color=None,
    line_label='series',
    marker_label='flagged slots',
    linewidth=0.8,
    markersize=14.0,
    xlabel='',
    ylabel='',
    legend_loc='upper left',
    ax=None,
    figsize=(6.3, 2.9),
)

Line plot of a series with its outlier-flagged slots marked.

Unlike visualize_outliers_hist and visualize_outliers_plotly_scatter, this function runs no outlier detection of its own. The flagged slots are read off the two frames as the positions where data_original holds a value and data holds NaN, which is exactly the contract of spotforecast2_safe.preprocessing.outlier.mark_outliers. The original series is drawn as a line and the flagged slots as markers at their original values, so the figure shows what the detector removed without re-running it.

Follows the stateless conventions of spotforecast2.plots.evaluation: the function returns a matplotlib.figure.Figure, never calls plt.show(), and does not mutate matplotlib.rcParams — styling and figure lifecycle stay with the caller.

Parameters

Name Type Description Default
data pd.DataFrame Frame after outlier marking, in which flagged slots hold NaN. required
data_original pd.DataFrame Frame before outlier marking. Must share the index of data and contain column. required
column str Name of the column to plot. required
line_color str | None Line color for the original series. None leaves the choice to matplotlib’s active color cycle. None
marker_color str | None Marker color for the flagged slots. None leaves the choice to matplotlib. None
line_label str Legend label for the series line. 'series'
marker_label str Legend label for the flagged-slot markers. 'flagged slots'
linewidth float Width of the series line. 0.8
markersize float Marker area forwarded to Axes.scatter as s. 14.0
xlabel str X-axis label. ''
ylabel str Y-axis label. ''
legend_loc str loc argument forwarded to ax.legend. 'upper left'
ax Axes | None Existing axes to draw into. When given, no new figure is created and the function returns ax.figure. None
figsize tuple[float, float] Figure size used when ax is not given. (6.3, 2.9)

Returns

Name Type Description
Figure A matplotlib.figure.Figure containing the plot.

Raises

Name Type Description
ValueError If either frame is empty, if column is missing from either frame, or if the two frames do not share the same index.

Examples

import matplotlib
matplotlib.use("Agg")  # non-interactive backend for doc rendering
import numpy as np
import pandas as pd

from spotforecast2.plots.outlier_plots import plot_outlier_flags

idx = pd.date_range("2025-01-01", periods=96, freq="15min", tz="UTC")
rng = np.random.default_rng(7)
original = pd.DataFrame(
    {"Actual Load": 10.0 + rng.normal(0.0, 0.05, 96)}, index=idx
)
flagged = original.copy()
flagged.iloc[[10, 40, 70], 0] = float("nan")

fig = plot_outlier_flags(
    flagged, original, "Actual Load", ylabel="load (scaled units)"
)
assert len(fig.axes[0].lines) == 1
assert fig.axes[0].collections[0].get_offsets().shape[0] == 3
print("plot_outlier_flags: 3 flagged slots marked")
plot_outlier_flags: 3 flagged slots marked

visualize_outliers_hist

plots.outlier_plots.visualize_outliers_hist(
    data,
    data_original,
    columns=None,
    contamination=0.01,
    random_state=1234,
    figsize=(10, 5),
    bins=50,
    **kwargs,
)

Visualize outliers in DataFrame using stacked histograms.

Creates a histogram for each specified column, displaying both regular data and detected outliers in different colors. Uses IsolationForest for outlier detection.

Parameters

Name Type Description Default
data pd.DataFrame The DataFrame with cleaned data (outliers may be NaN). required
data_original pd.DataFrame The original DataFrame before outlier detection. required
columns Optional[list[str]] List of column names to visualize. If None, all columns are used. Default: None. None
contamination float The estimated proportion of outliers in the dataset. Default: 0.01. 0.01
random_state int Random seed for reproducibility. Default: 1234. 1234
figsize tuple[int, int] Figure size as (width, height). Default: (10, 5). (10, 5)
bins int Number of histogram bins. Default: 50. 50
**kwargs Any Additional keyword arguments passed to plt.hist() (e.g., color, alpha, edgecolor, etc.). {}

Returns

Name Type Description
None None. Displays matplotlib figures.

Raises

Name Type Description
ValueError If data or data_original is empty, or if specified columns don’t exist.
ImportError If matplotlib is not installed.

Examples

import matplotlib
matplotlib.use("Agg")  # non-interactive backend for doc rendering
import numpy as np
import pandas as pd
from spotforecast2.plots.outlier_plots import visualize_outliers_hist

rng = np.random.default_rng(0)
normal_vals = rng.normal(loc=20.0, scale=2.0, size=28)
outlier_vals = [60.0, 65.0]  # two obvious outliers
data_original = pd.DataFrame(
    {"temperature": np.concatenate([normal_vals, outlier_vals])}
)
data_cleaned = data_original.copy()

# Renders a stacked histogram; outliers shown in red
visualize_outliers_hist(
    data_cleaned,
    data_original,
    columns=["temperature"],
    contamination=0.07,
    figsize=(6, 3),
    bins=15,
    alpha=0.7,
)
print("visualize_outliers_hist completed without error")
visualize_outliers_hist completed without error
/Users/bartz/workspace/spotforecast2/src/spotforecast2/plots/outlier_plots.py:126: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown
  plt.show()

visualize_outliers_plotly_scatter

plots.outlier_plots.visualize_outliers_plotly_scatter(
    data,
    data_original,
    columns=None,
    contamination=0.01,
    random_state=1234,
    **kwargs,
)

Visualize outliers in time series using Plotly scatter plots.

Creates an interactive time series plot for each specified column, showing regular data as a line and detected outliers as scatter points. Uses IsolationForest for outlier detection.

Parameters

Name Type Description Default
data pd.DataFrame The DataFrame with cleaned data (outliers may be NaN). required
data_original pd.DataFrame The original DataFrame before outlier detection. required
columns Optional[list[str]] List of column names to visualize. If None, all columns are used. Default: None. None
contamination float The estimated proportion of outliers in the dataset. Default: 0.01. 0.01
random_state int Random seed for reproducibility. Default: 1234. 1234
**kwargs Any Additional keyword arguments passed to go.Figure.update_layout() (e.g., template, height, etc.). {}

Returns

Name Type Description
None None. Displays Plotly figures.

Raises

Name Type Description
ValueError If data or data_original is empty, or if specified columns don’t exist.
ImportError If plotly is not installed.

Examples

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from spotforecast2_safe.preprocessing.outlier import get_outliers
from spotforecast2.plots.outlier_plots import visualize_outliers_plotly_scatter

rng = np.random.default_rng(0)
dates = pd.date_range("2024-01-01", periods=30, freq="h")
normal_vals = rng.normal(loc=20.0, scale=2.0, size=28)
outlier_vals_arr = [60.0, 65.0]  # two obvious outliers
data_original = pd.DataFrame(
    {"temperature": np.concatenate([normal_vals, outlier_vals_arr])},
    index=dates,
)
data_cleaned = data_original.copy()

# Verify that get_outliers detects the planted outliers before plotting
detected = get_outliers(
    data_original, data_original=data_original, contamination=0.07
)
assert len(detected["temperature"]) >= 1, "Expected at least one outlier"

# Renders an interactive Plotly time series with outliers marked in red
visualize_outliers_plotly_scatter(
    data_cleaned,
    data_original,
    columns=["temperature"],
    contamination=0.07,
)
print(f"Detected {len(detected['temperature'])} outlier(s) in 'temperature'")

Detected 3 outlier(s) in 'temperature'