Skip to content

Visualization

To plot straight from a pipeline result, the one-liner plot_result (or result.plot) names a concept and wires up the prepare function and context for you; available_concepts(result) lists what a given result can render:

from ob_analytics.visualization import plot_result

fig = plot_result(result, "depth_heatmap")          # level defaults to L2
fig = result.plot("trade_tape", "L3", backend="plotly")

For full control, the unified plot() dispatcher renders a concept at a resolution level on a chosen backend from already-prepared data. Prepare the payload with the matching helper in the public prepare namespace (friendly wrappers over the internal prepare-data functions) and spread it as keyword arguments:

from ob_analytics.visualization import plot, prepare

fig = plot("trade_tape", level="L2", **prepare.trades(trades))

backend="matplotlib" (default) returns a Matplotlib figure; backend="plotly" returns an interactive Plotly figure (requires pip install ob-analytics[interactive]). Renderers never call plt.show().

Every concept declares a resolution levelLevel.L2 (Market-By-Price aggregate) or Level.L3 (Market-By-Order, per order). A concept registered at a single level resolves it automatically, so you pass only the concept name; comparable concepts (both L2 and L3 registered) take an explicit level=.

Concepts with both L2 and L3 faces: trade_tape, order_activity, cancellations, book_snapshot, depth_chart, liquidity_at_touch. L2-only: time_series, depth_heatmap, volume_percentiles, events_histogram, hidden_executions, price_view, trade_size. L3-only: order_outcome, queue_position. Level-less analytics: vpin, order_flow_imbalance, kyle_lambda, ofi_horizon, trading_halts.

Dispatcher

plot

plot(
    concept: str,
    level: Level | None = _UNSET,
    *,
    backend: str = "matplotlib",
    ax: Axes | None = None,
    **data: Any,
) -> Any

Render concept at level on backend from already-prepared data.

Prepare data with the matching prepare_<concept>_data in :mod:ob_analytics.visualization._data (or a gallery helper) and spread it as keyword arguments::

from ob_analytics.visualization import plot
from ob_analytics.visualization import _data
fig = plot("trade_tape", backend="matplotlib",
           **_data.prepare_trades_data(trades))

Parameters:

Name Type Description Default
concept str

Plot concept, e.g. "trade_tape" or "order_activity".

required
level Level

Resolution level (Level.L2/Level.L3). Omit to auto-resolve when the concept is registered at a single level; required for a comparable concept registered at both.

_UNSET
backend str

Registered backend name (default "matplotlib").

'matplotlib'
ax Axes

Axes to draw on (matplotlib only; ignored by other backends).

None
**data Any

Prepared plot data, as returned by the matching prepare_* helper. May include theme=PlotTheme(...) to override :data:DEFAULT_THEME (matplotlib backend only; ignored by other backends).

{}

Returns:

Type Description
Figure or Figure

Raises:

Type Description
ValueError

If backend is not registered, or concept is comparable and no level was given.

KeyError

If concept (at the resolved level) is not registered.

Theme and Saving

Pass theme=PlotTheme(...) to plot() to override DEFAULT_THEME for a single call (matplotlib backend only); there is no global theme to set.

PlotTheme dataclass

PlotTheme(
    style: str = "white",
    context: str = "notebook",
    font_scale: float = 1.05,
    rc: dict[str, object] = (
        lambda: {
            "axes.grid": True,
            "grid.linestyle": ":",
            "grid.alpha": 0.35,
            "axes.spines.top": False,
            "axes.spines.right": False,
            "axes.edgecolor": "#444444",
            "axes.titlelocation": "left",
            "axes.titleweight": "bold",
            "lines.linewidth": 2.0,
        }
    )(),
)

Configurable visual theme for ob-analytics plots.

Attributes:

Name Type Description
style str

Seaborn style name (e.g. "darkgrid", "whitegrid").

context str

Seaborn context name (e.g. "notebook", "talk").

font_scale float

Global font scaling factor.

rc dict[str, object]

Matplotlib rc overrides applied on top of the seaborn theme.

DEFAULT_THEME module-attribute

DEFAULT_THEME: PlotTheme = PlotTheme()

save_figure

save_figure(
    fig: Figure,
    path: str | Path,
    *,
    dpi: int = 150,
    **kwargs: object,
) -> None

Save a matplotlib fig to path with sensible defaults.

Parameters:

Name Type Description Default
fig Figure

The matplotlib figure to save.

required
path str or Path

Destination file path (e.g. "output/plot.png").

required
dpi int

Resolution in dots per inch (default 150).

150
**kwargs object

Additional keyword arguments forwarded to :meth:~matplotlib.figure.Figure.savefig. Pass bbox_inches="tight" explicitly to crop to artist extents — it is not the default because it forces a second full draw (roughly doubling save time on dense figures), and every renderer already applies tight_layout.

{}

infer_volume_scale module-attribute

infer_volume_scale = infer_volume_scale

Renderer registry

Backends self-register their renderers into RENDERERS, keyed by the coordinate (concept, level, backend) (where level is a Level or None for level-less analytics). Register a whole new backend module with register_plot_backend, or a single renderer directly with RENDERERS.register((concept, level, backend), fn).

register_plot_backend

register_plot_backend(name: str, module_path: str) -> None

Register a visualization backend module.

The module at module_path must call RENDERERS.register((concept, level, name), fn) for each plot it supports (typically at import time). It is imported lazily on the first :func:plot call that targets name.

Parameters:

Name Type Description Default
name str

Backend name used in plot(..., backend=name).

required
module_path str

Dotted import path, e.g. "my_package._bokeh_backend".

required

Examples:

>>> from ob_analytics.visualization import register_plot_backend
>>> register_plot_backend("bokeh", "my_pkg._bokeh")

RENDERERS module-attribute

RENDERERS: Registry[
    tuple[str, Level | None, str], RendererFn
] = Registry("renderer")