Skip to content

Dataframe

dataframe

MojoNamespace

Python
MojoNamespace(df: DataFrame)

Enhanced Polars DataFrame for MuJoCo Mojo telemetry.

Supports hierarchical signal filtering and common physics transformations.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def __init__(self, df: pl.DataFrame):
    self._df = df

time property

Python
time: Series

Access the master simulation time column.

rotatable_bases property

Python
rotatable_bases: set[str]

Returns the unique base names for 3-component vectors (x, y, z).

quaternion_bases property

Python
quaternion_bases: set[str]

Returns the unique base names for 4-component quaternions (w, x, y, z).

rotatable_columns property

Python
rotatable_columns: list[tuple[str, str, str]]

Returns column names ending in :x, :y, or :z (excluding quaternions which end with :w).

quaternion_columns property

Python
quaternion_columns: list[str]

Returns all columns that form a full quaternion group. Specifically looks for columns ending with quat:w, quat:x, quat:y, quat:z.

select_category

Python
select_category(
    category: SignalCategory | str,
) -> MojoDataFrame

Filter columns belonging to a specific SignalCategory (e.g., 'Bodies').

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_category(self, category: SignalCategory | str) -> MojoDataFrame:
    """Filter columns belonging to a specific SignalCategory (e.g., 'Bodies')."""
    return _MojoFrame.from_pl(self._df.select(pl.col(rf"^{category}/.*$")))

select_name

Python
select_name(name: str) -> MojoDataFrame

General filter for columns associated with a specific object name (e.g., 'racket').

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_name(self, name: str) -> MojoDataFrame:
    """General filter for columns associated with a specific object name (e.g., 'racket')."""
    # Matches Category/Name:Attr or Category/Name/Sub:Attr
    return _MojoFrame.from_pl(self._df.select(pl.col(rf"^[^/]+/{name}/.*$")))

select_channel

Python
select_channel(channel: str) -> MojoDataFrame

Selects all components of a specific channel across any category.

Matches the logical 'folder' before the attribute separator. Example: 'xpos' matches 'Bodies/Hand/xpos:x' and 'Bodies/Hand/xpos:y'.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_channel(self, channel: str) -> MojoDataFrame:
    """
    Selects all components of a specific channel across any category.

    Matches the logical 'folder' before the attribute separator.
    Example: 'xpos' matches 'Bodies/Hand/xpos:x' and 'Bodies/Hand/xpos:y'.
    """
    # Regex Breakdown:
    # ^.*/        -> Start and match any prefix ending in a slash (the path)
    # {channel}   -> The specific channel name (e.g., xpos)
    # (?::.*)?    -> Optionally match a colon followed by any attribute component
    # $           -> End of string
    return _MojoFrame.from_pl(self._df.select(pl.col(rf"^.*/{channel}(?::.*)?$")))

select_attribute

Python
select_attribute(attr: str) -> MojoDataFrame

Selects a specific attribute across all categories and objects. Matches exact scalars (':nutation_deg') or vector groups (':x').

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_attribute(self, attr: str) -> MojoDataFrame:
    """
    Selects a specific attribute across all categories and objects.
    Matches exact scalars (':nutation_deg') or vector groups (':x').
    """
    # Matches ':attr' at the end of a string OR ':attr' followed by anything
    return _MojoFrame.from_pl(self._df.select(pl.col(rf"^.*/{attr}(:.*)?$")))

select_joint

Python
select_joint(name: JointName) -> MojoDataFrame

Select all signals belonging to a specific Joint (qpos, qvel, etc.).

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_joint(self, name: JointName) -> MojoDataFrame:
    """Select all signals belonging to a specific Joint (qpos, qvel, etc.)."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.JOINTS}/{name}/.*$"))
    )

select_site

Python
select_site(name: SiteName) -> MojoDataFrame

Select all signals recorded at a specific Site.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_site(self, name: SiteName) -> MojoDataFrame:
    """Select all signals recorded at a specific Site."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.SITES}/{name}/.*$"))
    )

select_geom

Python
select_geom(name: GeomName) -> MojoDataFrame

Select all signals associated with a specific Geom (contacts, etc.).

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_geom(self, name: GeomName) -> MojoDataFrame:
    """Select all signals associated with a specific Geom (contacts, etc.)."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.GEOMS}/{name}/.*$"))
    )

select_sensor

Python
select_sensor(name: SensorName) -> MojoDataFrame

Select data from a specific named Sensor.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_sensor(self, name: SensorName) -> MojoDataFrame:
    """Select data from a specific named Sensor."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.SENSORS}/{name}/.*$"))
    )

select_actuator

Python
select_actuator(name: ActuatorName) -> MojoDataFrame

Select data from a specific Actuator.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_actuator(self, name: ActuatorName) -> MojoDataFrame:
    """Select data from a specific Actuator."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.ACTUATORS}/{name}/.*$"))
    )

select_tendon

Python
select_tendon(name: TendonName) -> MojoDataFrame

Select data from a specific Tendon.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_tendon(self, name: TendonName) -> MojoDataFrame:
    """Select data from a specific Tendon."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.TENDONS}/{name}/.*$"))
    )

select_camera

Python
select_camera(name: CameraName) -> MojoDataFrame

Select pose or FOV data from a specific Camera.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_camera(self, name: CameraName) -> MojoDataFrame:
    """Select pose or FOV data from a specific Camera."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.CAMERAS}/{name}/.*$"))
    )

select_light

Python
select_light(name: LightName) -> MojoDataFrame

Select pose or intensity data from a specific Light.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_light(self, name: LightName) -> MojoDataFrame:
    """Select pose or intensity data from a specific Light."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.LIGHTS}/{name}/.*$"))
    )

select_equality

Python
select_equality(name: EqualityName) -> MojoDataFrame

Select force/error data from an Equality constraint.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_equality(self, name: EqualityName) -> MojoDataFrame:
    """Select force/error data from an Equality constraint."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.CONSTRAINTS}/{name}/.*$"))
    )

select_plugin

Python
select_plugin(name: InstanceName) -> MojoDataFrame

Select custom state data from a specific Plugin Instance.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_plugin(self, name: InstanceName) -> MojoDataFrame:
    """Select custom state data from a specific Plugin Instance."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.PLUGINS}/{name}/.*$"))
    )

select_flex

Python
select_flex(name: FlexName) -> MojoDataFrame

Select vertex/stress data from a Deformable Flex object.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def select_flex(self, name: FlexName) -> MojoDataFrame:
    """Select vertex/stress data from a Deformable Flex object."""
    return _MojoFrame.from_pl(
        self._df.select(pl.col(rf"^{SignalCategory.DEFORMABLES}/{name}/.*$"))
    )

get_manifest

Python
get_manifest() -> ColumnManifest

Returns the structured manifest used by the frontend.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def get_manifest(self) -> ColumnManifest:
    """Returns the structured manifest used by the frontend."""
    return {
        "all": self._df.columns,
        "rotatable_vectors": sorted(list(self.rotatable_bases)),
        "available_quats": sorted(list(self.quaternion_bases)),
    }

with_rotation

Python
with_rotation(
    quat_base: str, invert: bool = True
) -> MojoDataFrame

Rotates all 3D vectors into a new frame using the specified quaternion.

Parameters:

Name Type Description Default
quat_base str

Prefix for the [w,x,y,z] quaternion group.

required
invert bool

If True, performs World to Local transformation (use False with the same quat_base to revert the rotation). Defaults to True.

True

Returns:

Name Type Description
Self MojoDataFrame

DataFrame with transformed :x, :y, :z columns.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def with_rotation(self, quat_base: str, invert: bool = True) -> MojoDataFrame:
    """
    Rotates all 3D vectors into a new frame using the specified quaternion.

    Args:
        quat_base (str): Prefix for the [w,x,y,z] quaternion group.
        invert (bool, optional): If True, performs World to Local transformation (use False with the same `quat_base` to revert the rotation). Defaults to True.

    Returns:
        Self: DataFrame with transformed :x, :y, :z columns.

    """
    # validate the quaternion family
    if quat_base not in self.quaternion_bases:
        logger.warning(
            f"Rotation failed: Quaternion base '{quat_base}' not found (please see the quaternion_bases property for valid columns)."
        )
        return _MojoFrame.from_pl(self._df)

    # extract roation data (N, 4)
    q_cols = [f"{quat_base}:{k}" for k in "xyzw"]  # w last for scipy!
    qs = self._df.select(q_cols).to_numpy()
    transformer = R.from_quat(qs)
    if invert:
        transformer = transformer.inv()

    # rotate all of the rotatables
    new_columns = []
    for base in self.rotatable_bases:
        v_cols = [f"{base}:x", f"{base}:y", f"{base}:z"]
        vs = self._df.select(v_cols).to_numpy()

        v_rot = transformer.apply(vs)  # apply the rotation here!

        # prepare a new series for overwriting
        new_columns.extend(
            [
                pl.Series(name=f"{base}:x", values=v_rot[:, 0]),
                pl.Series(name=f"{base}:y", values=v_rot[:, 1]),
                pl.Series(name=f"{base}:z", values=v_rot[:, 2]),
            ]
        )

    # overwrite with the new rotated data
    return _MojoFrame.from_pl(self._df.with_columns(new_columns))

with_filter_map

Python
with_filter_map(
    filter_map: dict[str, list[AnyFilter]],
    omit_time: bool = True,
) -> MojoDataFrame

Applies specific filter stacks to mapped columns.

Parameters:

Name Type Description Default
filter_map dict[str, list[AnyFilter]]

Dictionary mapping column names to a list of filters.

required
omit_time bool

If True, skips the 'time' column even if present in the map. Defaults to True.

True

Returns:

Name Type Description
Self MojoDataFrame

DataFrame with the transformed columns overwritten.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def with_filter_map(
    self, filter_map: dict[str, list[AnyFilter]], omit_time: bool = True
) -> MojoDataFrame:
    """
    Applies specific filter stacks to mapped columns.

    Args:
        filter_map (dict[str, list[AnyFilter]]): Dictionary mapping column names to a list of filters.
        omit_time (bool, optional): If True, skips the 'time' column even if present in the map. Defaults to True.

    Returns:
        Self: DataFrame with the transformed columns overwritten.

    """
    exprs = []
    for col_name, filters in filter_map.items():
        if col_name not in self._df.columns:
            continue

        if omit_time and col_name == TIME_COLUMN_NAME:
            continue

        expr = pl.col(col_name)
        for f in filters:
            expr = f.apply(expr)

        exprs.append(expr.alias(col_name))

    return _MojoFrame.from_pl(self._df.with_columns(exprs))

with_filters

Python
with_filters(
    filters: list[AnyFilter],
    columns: list[str] | None = None,
    omit_time: bool = True,
) -> MojoDataFrame

Applies a sequential stack of filters to the specified or all numeric columns.

Parameters:

Name Type Description Default
filters list[AnyFilter]

List of Filter objects to apply in order (e.g., LowPass -> Derivative).

required
columns list[str] | None

Specific columns to transform. If None, applies to all available columns. Defaults to None.

None
omit_time bool

If True, prevents filters from being applied to the 'time' column. Defaults to True.

True

Returns:

Name Type Description
Self MojoDataFrame

DataFrame with the transformed columns overwritten.

Source code in src/mujoco_mojo/utils/dataframe.py
Python
def with_filters(
    self,
    filters: list[AnyFilter],
    columns: list[str] | None = None,
    omit_time: bool = True,
) -> MojoDataFrame:
    """
    Applies a sequential stack of filters to the specified or all numeric columns.

    Args:
        filters (list[AnyFilter]): List of Filter objects to apply in order (e.g., LowPass -> Derivative).
        columns (list[str] | None, optional): Specific columns to transform. If None, applies to all available columns. Defaults to None.
        omit_time (bool, optional): If True, prevents filters from being applied to the 'time' column. Defaults to True.

    Returns:
        Self: DataFrame with the transformed columns overwritten.

    """
    target_cols = columns or self._df.columns
    filter_map = {col: filters for col in target_cols}
    return self.with_filter_map(filter_map, omit_time=omit_time)