Covariance ellipsoids in 3D
Use Ellipsoids3D.
To draw a 3×3 covariance matrix, take its eigendecomposition:
- the half sizes of the ellipsoid are
k * sqrt(eigenvalues), wherekis the number of standard deviations, - the rotation is the matrix of eigenvectors (one eigenvector per column).
Put the rotation and the mean in a Transform3D on the same entity:
import numpy as np
import rerun as rr
rr.init("rerun_example_covariance_ellipsoid", spawn=True)
mean = np.array([1.0, 2.0, 0.5])
covariance = np.array([
[0.40, 0.10, 0.00],
[0.10, 0.20, 0.05],
[0.00, 0.05, 0.10],
])
eigenvalues, eigenvectors = np.linalg.eigh(covariance)
k = 2.0 # Two standard deviations
rr.log("estimate/covariance", rr.Transform3D(translation=mean, mat3x3=eigenvectors))
rr.log("estimate/covariance", rr.Ellipsoids3D(half_sizes=[k * np.sqrt(eigenvalues)]))To draw many ellipsoids in one entity, pass centers and one rotation per ellipsoid with quaternions instead.
You can convert a rotation matrix to a quaternion with, for example, scipy.spatial.transform.Rotation.from_matrix(eigenvectors).as_quat() (which returns xyzw).
If np.linalg.det(eigenvectors) is negative, flip the sign of one column first, so that the matrix is a rotation.
Covariance ellipses in 2D
Ellipses2D draws ellipses aligned with the X and Y axes.
It has no rotation, so for a 2×2 covariance with correlation, draw the outline as a LineStrips2D:
mean = np.array([50.0, 40.0])
covariance = np.array([[30.0, 12.0], [12.0, 10.0]])
k = 2.0
eigenvalues, eigenvectors = np.linalg.eigh(covariance)
angles = np.linspace(0.0, 2.0 * np.pi, 64)
unit_circle = np.stack([np.cos(angles), np.sin(angles)])
outline = mean + (eigenvectors @ (k * np.sqrt(eigenvalues)[:, None] * unit_circle)).T
rr.log("estimate/covariance_2d", rr.LineStrips2D([outline]))Error bands in plots
For one-dimensional values over time, Measurements logs each value together with its variance.
The time series view draws a band of one standard deviation around the line.
Measurements is unstable: its data format may change in future releases.
"""Log scalar measurements with variances over time."""
import math
import rerun as rr
rr.init("rerun_example_measurements_simple", spawn=True)
# Two parallel pressure sensors (in Pa), each with slowly drifting variance.
for step in range(64):
rr.set_time("step", sequence=step)
pressures = [
101_325.0 + 50.0 * math.sin(step / 10.0),
101_300.0 + 30.0 * math.cos(step / 8.0),
]
variances = [
100.0 + 25.0 * math.sin(step / 7.0),
80.0 + 15.0 * math.cos(step / 11.0),
]
rr.log(
"pressure",
rr.Measurements(values=pressures, variances=variances, units="Pa"),
)
Gaussian splats
GaussianSplats3D draws 3D Gaussians with a center, per-axis scales (standard deviations), a rotation, and a color with opacity.
It is meant for 3D Gaussian Splatting (3DGS) reconstructions, but you can also use it to show many probability distributions at once.
GaussianSplats3D is unstable: its data format may change in future releases.
3DGS .ply files are loaded as GaussianSplats3D when you open them in the Viewer, or log them with rr.log_file_from_path.