Skip to content
Feeding a clanker? Grab this page as raw .md

CubeWidget API#

Bases: AnyWidget

Select a plane, line, and point by progressively locking cube axes.

Clicking an axis locks it and reveals a slider for its value. The first locked axis selects a plane, the second selects a line, and the third selects a point. Lock order is exposed so downstream code can preserve the same progressive slicing semantics.

Examples:

import marimo as mo
from wigglystuff import CubeWidget

cube = mo.ui.anywidget(
    CubeWidget(
        x_axis={"name": "Angle", "values": [0, 45, 90]},
        y_axis={"name": "Force", "values": [0, 50, 100]},
        z_axis={"name": "Time", "values": [0, 1, 2]},
    )
)
cube

Parameters:

Name Type Description Default
x_axis dict[str, Any] | None

X-axis configuration with a display name and numeric values defining its range.

None
y_axis dict[str, Any] | None

Y-axis configuration with a display name and numeric values defining its range.

None
z_axis dict[str, Any] | None

Z-axis configuration with a display name and numeric values defining its range.

None
**kwargs Any

Forwarded to anywidget.AnyWidget.

{}
Source code in wigglystuff/cube_widget.py
def __init__(
    self,
    x_axis: dict[str, Any] | None = None,
    y_axis: dict[str, Any] | None = None,
    z_axis: dict[str, Any] | None = None,
    **kwargs: Any,
) -> None:
    supplied_axis_values = kwargs.pop("axis_values", None)
    self._initializing_axes = True
    try:
        super().__init__(
            x_axis=_axis_default("X") if x_axis is None else x_axis,
            y_axis=_axis_default("Y") if y_axis is None else y_axis,
            z_axis=_axis_default("Z") if z_axis is None else z_axis,
            **kwargs,
        )
    finally:
        self._initializing_axes = False

    initial_axis_values = {
        axis_key: _axis_midpoint(self._get_axis_config(axis_key))
        for axis_key in _AXIS_KEYS
    }
    if supplied_axis_values is not None:
        if not isinstance(supplied_axis_values, dict):
            raise ValueError("axis_values must be a dictionary.")
        initial_axis_values.update(supplied_axis_values)
    self.axis_values = initial_axis_values

    self.observe(
        self._update_outputs,
        names=[
            "locked_order",
            "axis_values",
            "x_axis",
            "y_axis",
            "z_axis",
        ],
    )
    self._update_outputs()

lock_axis #

lock_axis(axis_key: str, value: Real | None = None) -> None

Lock an axis, optionally assigning its current value.

Source code in wigglystuff/cube_widget.py
def lock_axis(self, axis_key: str, value: Real | None = None) -> None:
    """Lock an axis, optionally assigning its current value."""
    self._require_axis_key(axis_key)
    if value is not None:
        if not _is_finite_number(value):
            raise ValueError("value must be a finite number.")
        config = self._get_axis_config(axis_key)
        low = min(config["values"])
        high = max(config["values"])
        if not _value_in_axis_range(value, config):
            raise ValueError(
                f"value must be within the {config['name']} axis range "
                f"[{low}, {high}]."
            )
    if axis_key not in self.locked_order:
        self.locked_order = [*self.locked_order, axis_key]
    if value is not None:
        self.axis_values = {**self.axis_values, axis_key: value}

reset #

reset() -> None

Return to the volume view by unlocking every axis.

Source code in wigglystuff/cube_widget.py
def reset(self) -> None:
    """Return to the volume view by unlocking every axis."""
    self.locked_order = []

unlock_axis #

unlock_axis(axis_key: str) -> None

Unlock an axis while preserving the order of the remaining axes.

Source code in wigglystuff/cube_widget.py
def unlock_axis(self, axis_key: str) -> None:
    """Unlock an axis while preserving the order of the remaining axes."""
    self._require_axis_key(axis_key)
    if axis_key in self.locked_order:
        self.locked_order = [
            key for key in self.locked_order if key != axis_key
        ]

Synced traitlets#

Traitlet Type Notes
x_axis dict X-axis display name and numeric values.
y_axis dict Y-axis display name and numeric values.
z_axis dict Z-axis display name and numeric values.
locked_order list[str] Axis keys in plane → line → point lock order.
axis_values dict[str, float] Current value for each axis key.
plane dict | None First locked axis display name and value.
line dict | None Second locked axis display name and value.
point dict | None Third locked axis display name and value.

Helpers#

  • lock_axis(axis_key, value=None) locks an axis and optionally sets its value.
  • unlock_axis(axis_key) removes an axis from the lock order.
  • reset() clears every lock while preserving the current axis values.