Send entire timeseries at once
Sometimes you want to send big chunks of data to Rerun efficiently. To do so, you can use send_columns
.
send_columns
lets you efficiently log the state of an entity over time, logging multiple time and component columns in one call.
In contrast to the log
function, send_columns
does NOT add any other timelines to the data. Neither the built-in timelines log_time
and log_tick
, nor any user timelines. Only the timelines explicitly included in the call to send_columns
will be included.
API docs of send_columns
:
Using send_columns
for logging scalars using-sendcolumns-for-logging-scalars
#!/usr/bin/env python3
"""Use the `send_columns` API to send scalars over time in a single call."""
from __future__ import annotations
import numpy as np
import rerun as rr
rr.init("rerun_example_send_columns", spawn=True)
times = np.arange(0, 64)
scalars = np.sin(times / 10.0)
rr.send_columns(
"scalars",
times=[rr.TimeSequenceColumn("step", times)],
components=[rr.components.ScalarBatch(scalars)],
)
Using send_columns
for logging images using-sendcolumns-for-logging-images
"""Send multiple images at once using `send_columns`."""
import numpy as np
import rerun as rr
rr.init("rerun_example_image_send_columns", spawn=True)
# Timeline on which the images are distributed.
times = np.arange(0, 20)
# Create a batch of images with a moving rectangle.
width, height = 300, 200
images = np.zeros((len(times), height, width, 3), dtype=np.uint8)
images[:, :, :, 2] = 255
for t in times:
images[t, 50:150, (t * 10) : (t * 10 + 100), 1] = 255
# Log the ImageFormat and indicator once, as static.
format_static = rr.components.ImageFormat(width=width, height=height, color_model="RGB", channel_datatype="U8")
rr.log("images", [format_static, rr.Image.indicator()], static=True)
# Send all images at once.
rr.send_columns(
"images",
times=[rr.TimeSequenceColumn("step", times)],
# Reshape the images so `ImageBufferBatch` can tell that this is several blobs.
#
# Note that the `ImageBufferBatch` consumes arrays of bytes,
# so if you have a different channel datatype than `U8`, you need to make sure
# that the data is converted to arrays of bytes before passing it to `ImageBufferBatch`.
components=[rr.components.ImageBufferBatch(images.reshape(len(times), -1))],
)
Using send_columns
for logging points using-sendcolumns-for-logging-points
Each row in the component column can be a batch of data, e.g. a batch of positions. This lets you log the evolution of a point cloud over time efficiently.
"""Use the `send_columns` API to send several point clouds over time in a single call."""
from __future__ import annotations
import numpy as np
import rerun as rr
rr.init("rerun_example_send_columns_arrays", spawn=True)
# Prepare a point cloud that evolves over time 5 timesteps, changing the number of points in the process.
times = np.arange(10, 15, 1.0)
positions = [
[[1.0, 0.0, 1.0], [0.5, 0.5, 2.0]],
[[1.5, -0.5, 1.5], [1.0, 1.0, 2.5], [-0.5, 1.5, 1.0], [-1.5, 0.0, 2.0]],
[[2.0, 0.0, 2.0], [1.5, -1.5, 3.0], [0.0, -2.0, 2.5], [1.0, -1.0, 3.5]],
[[-2.0, 0.0, 2.0], [-1.5, 1.5, 3.0], [-1.0, 1.0, 3.5]],
[[1.0, -1.0, 1.0], [2.0, -2.0, 2.0], [3.0, -1.0, 3.0], [2.0, 0.0, 4.0]],
]
positions_arr = np.concatenate(positions)
# At each time stamp, all points in the cloud share the same but changing color.
colors = [0xFF0000FF, 0x00FF00FF, 0x0000FFFF, 0xFFFF00FF, 0x00FFFFFF]
rr.send_columns(
"points",
times=[rr.TimeSecondsColumn("time", times)],
components=[
rr.Points3D.indicator(),
rr.components.Position3DBatch(positions_arr).partition([len(row) for row in positions]),
rr.components.ColorBatch(colors),
],
)
Using send_columns
for logging custom components using-sendcolumns-for-logging-custom-components
An entire batch of a custom component can be logged at once using rr.AnyBatchValue
along with send_column
:
"""Use `AnyBatchValue` and `send_column` to send an entire column of custom data to Rerun."""
from __future__ import annotations
import numpy as np
import rerun as rr
rr.init("rerun_example_any_batch_value_send_columns", spawn=True)
N = 64
timestamps = np.arange(0, N)
one_per_timestamp = np.sin(timestamps / 10.0)
ten_per_timestamp = np.cos(np.arange(0, N * 10) / 100.0)
rr.send_columns(
"/",
times=[rr.TimeSequenceColumn("step", timestamps)],
components=[
# log one value per timestamp
rr.AnyBatchValue("custom_component_single", one_per_timestamp),
# log ten values per timestamp
rr.AnyBatchValue("custom_component_multi", ten_per_timestamp).partition([10] * N),
],
)
The rr.AnyValues
class can also be used to log multiple components at a time.
It does not support partitioning, so each component batch and the timeline must hold the same number of elements.
"""Use `AnyValues` and `send_column` to send entire columns of custom data to Rerun."""
from __future__ import annotations
import numpy as np
import rerun as rr
rr.init("rerun_example_any_values_send_columns", spawn=True)
timestamps = np.arange(0, 64)
# Log two components, named "sin" and "cos", with the corresponding values
values = rr.AnyValues(
sin=np.sin(timestamps / 10.0),
cos=np.cos(timestamps / 10.0),
)
rr.send_columns(
"/",
times=[rr.TimeSequenceColumn("step", timestamps)],
components=values.as_component_batches(),
)