Skip to content

Commit

Permalink
Update all examples that use TimeSeriesScalar to use Scalar inste…
Browse files Browse the repository at this point in the history
…ad (#5042)

### What

Also fixes missing serialization of `StrokeWidth` & `MarkerSize`


![image](https://github.com/rerun-io/rerun/assets/1220815/44a118d4-5dc7-4c6d-a79b-29f83ac7eb77)


blocked by a few things:
* [x] text labels should go on SeriesLine/SeriesPlot  #5043
* [x] SeriesPoint doesn't have a `MarkerSize` component yet #5057
* [x] Need to fix heuristic for only having Scalar -> Line #5050

---------

Co-authored-by: Clement Rey <[email protected]>
  • Loading branch information
Wumpf and teh-cmc authored Feb 6, 2024
1 parent 91a41b4 commit b9cd458
Show file tree
Hide file tree
Showing 27 changed files with 189 additions and 111 deletions.
6 changes: 2 additions & 4 deletions crates/re_types/src/archetypes/scalar.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions crates/re_types/src/archetypes/time_series_scalar.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 19 additions & 17 deletions docs/code-examples/all/scalar_multiple_plots.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,29 @@ int main() {

int64_t lcg_state = 0;

// Set up plot styling:
// They are logged timeless as they don't change over time and apply to all timelines.
// Log two lines series under a shared root so that they show in the same plot by default.
rec.log_timeless(
"trig/sin",
rerun::SeriesLine().with_color({255, 0, 0}).with_name("sin(0.01t)")
);
rec.log_timeless(
"trig/cos",
rerun::SeriesLine().with_color({0, 255, 0}).with_name("cos(0.01t)")
);
// Log scattered points under a different root so that they show in a different plot by default.
rec.log_timeless("scatter/lcg", rerun::SeriesPoint());

// Log the data on a timeline called "step".
for (int t = 0; t < static_cast<int>(TAU * 2.0 * 100.0); ++t) {
rec.set_time_sequence("step", t);

// Log two time series under a shared root so that they show in the same plot by default.
rec.log(
"trig/sin",
rerun::TimeSeriesScalar(sin(t / 100.0)).with_label("sin(0.01t)").with_color({255, 0, 0})
);
rec.log(
"trig/cos",
rerun::TimeSeriesScalar(cos(static_cast<float>(t) / 100.0f))
.with_label("cos(0.01t)")
.with_color({0, 255, 0})
);

// Log scattered points under a different root so that it shows in a different plot by default.
rec.log("trig/sin", rerun::Scalar(sin(t / 100.0)));
rec.log("trig/cos", rerun::Scalar(cos(static_cast<float>(t) / 100.0f)));

lcg_state =
1140671485 * lcg_state + 128201163 % 16777216; // simple linear congruency generator
rec.log(
"scatter/lcg",
rerun::TimeSeriesScalar(static_cast<float>(lcg_state)).with_scattered(true)
);
rec.log("scatter/lcg", rerun::Scalar(static_cast<float>(lcg_state)));
}
}
17 changes: 12 additions & 5 deletions docs/code-examples/all/scalar_multiple_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@
rr.init("rerun_example_scalar_multiple_plots", spawn=True)
lcg_state = np.int64(0)

# Set up plot styling:
# They are logged timeless as they don't change over time and apply to all timelines.
# Log two lines series under a shared root so that they show in the same plot by default.
rr.log("trig/sin", rr.SeriesLine(color=[255, 0, 0], name="sin(0.01t)"), timeless=True)
rr.log("trig/cos", rr.SeriesLine(color=[0, 255, 0], name="cos(0.01t)"), timeless=True)
# Log scattered points under a different root so that they show in a different plot by default.
rr.log("scatter/lcg", rr.SeriesPoint(), timeless=True)

# Log the data on a timeline called "step".
for t in range(0, int(tau * 2 * 100.0)):
rr.set_time_sequence("step", t)

# Log two time series under a shared root so that they show in the same plot by default.
rr.log("trig/sin", rr.TimeSeriesScalar(sin(float(t) / 100.0), label="sin(0.01t)", color=[255, 0, 0]))
rr.log("trig/cos", rr.TimeSeriesScalar(cos(float(t) / 100.0), label="cos(0.01t)", color=[0, 255, 0]))
rr.log("trig/sin", rr.Scalar(sin(float(t) / 100.0)))
rr.log("trig/cos", rr.Scalar(cos(float(t) / 100.0)))

# Log scattered points under a different root so that they shows in a different plot by default.
lcg_state = (1140671485 * lcg_state + 128201163) % 16777216 # simple linear congruency generator
rr.log("scatter/lcg", rr.TimeSeriesScalar(lcg_state, scattered=True))
rr.log("scatter/lcg", rr.Scalar(lcg_state))
37 changes: 21 additions & 16 deletions docs/code-examples/all/scalar_multiple_plots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,37 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let rec = rerun::RecordingStreamBuilder::new("rerun_example_scalar_multiple_plots").spawn()?;
let mut lcg_state = 0_i64;

// Set up plot styling:
// They are logged timeless as they don't change over time and apply to all timelines.
// Log two lines series under a shared root so that they show in the same plot by default.
rec.log_timeless(
"trig/sin",
&rerun::SeriesLine::new()
.with_color([255, 0, 0])
.with_name("sin(0.01t)"),
)?;
rec.log_timeless(
"trig/cos",
&rerun::SeriesLine::new()
.with_color([0, 255, 0])
.with_name("cos(0.01t)"),
)?;
// Log scattered points under a different root so that they show in a different plot by default.
rec.log_timeless("scatter/lcg", &rerun::SeriesPoint::new())?;

for t in 0..((std::f32::consts::TAU * 2.0 * 100.0) as i64) {
rec.set_time_sequence("step", t);

// Log two time series under a shared root so that they show in the same plot by default.
rec.log(
"trig/sin",
&rerun::TimeSeriesScalar::new((t as f64 / 100.0).sin())
.with_label("sin(0.01t)")
.with_color([255, 0, 0]),
)?;
rec.log(
"trig/cos",
&rerun::TimeSeriesScalar::new((t as f64 / 100.0).cos())
.with_label("cos(0.01t)")
.with_color([0, 255, 0]),
)?;
rec.log("trig/sin", &rerun::Scalar::new((t as f64 / 100.0).sin()))?;
rec.log("trig/cos", &rerun::Scalar::new((t as f64 / 100.0).cos()))?;

// Log scattered points under a different root so that it shows in a different plot by default.
lcg_state = (1140671485_i64
.wrapping_mul(lcg_state)
.wrapping_add(128201163))
% 16777216; // simple linear congruency generator
rec.log(
"scatter/lcg",
&rerun::TimeSeriesScalar::new(lcg_state as f64).with_scattered(true),
)?;
rec.log("scatter/lcg", &rerun::Scalar::new(lcg_state as f64))?;
}

Ok(())
Expand Down
3 changes: 2 additions & 1 deletion docs/code-examples/all/scalar_simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ int main() {
const auto rec = rerun::RecordingStream("rerun_example_scalar");
rec.spawn().exit_on_failure();

// Log the data on a timeline called "step".
for (int step = 0; step < 64; ++step) {
rec.set_time_sequence("step", step);
rec.log("scalar", rerun::TimeSeriesScalar(std::sin(static_cast<double>(step) / 10.0)));
rec.log("scalar", rerun::Scalar(std::sin(static_cast<double>(step) / 10.0)));
}
}
3 changes: 2 additions & 1 deletion docs/code-examples/all/scalar_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

rr.init("rerun_example_scalar", spawn=True)

# Log the data on a timeline called "step".
for step in range(0, 64):
rr.set_time_sequence("step", step)
rr.log("scalar", rr.TimeSeriesScalar(math.sin(step / 10.0)))
rr.log("scalar", rr.Scalar(math.sin(step / 10.0)))
6 changes: 2 additions & 4 deletions docs/code-examples/all/scalar_simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
let rec = rerun::RecordingStreamBuilder::new("rerun_example_scalar").spawn()?;

// Log the data on a timeline called "step".
for step in 0..64 {
rec.set_time_sequence("step", step);
rec.log(
"scalar",
&rerun::TimeSeriesScalar::new((step as f64 / 10.0).sin()),
)?;
rec.log("scalar", &rerun::Scalar::new((step as f64 / 10.0).sin()))?;
}

Ok(())
Expand Down
8 changes: 4 additions & 4 deletions docs/content/howto/ros2-nav-turtlebot.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ Note that because we previously called `set_time_nanos` in this callback, this t
be logged to the same point on the timeline as the data, using a timestamp looked up from TF at the
matching timepoint.

### Odometry to rr.TimeSeriesScalar and rr.Transform3D
When receiving odometry messages, we log the linear and angular velocities using `rr.TimeSeriesScalar`.
### Odometry to rr.Scalar and rr.Transform3D
When receiving odometry messages, we log the linear and angular velocities using `rr.Scalar`.
Additionally, since we know that odometry will also update the `map/robot` transform, we use
this as a cue to look up the corresponding transform and log it.
```python
Expand All @@ -213,8 +213,8 @@ def odom_callback(self, odom: Odometry) -> None:
rr.set_time_nanos("ros_time", time.nanoseconds)

# Capture time-series data for the linear and angular velocities
rr.log("odometry/vel", rr.TimeSeriesScalar(odom.twist.twist.linear.x))
rr.log("odometry/ang_vel", rr.TimeSeriesScalar(odom.twist.twist.angular.z))
rr.log("odometry/vel", rr.Scalar(odom.twist.twist.linear.x))
rr.log("odometry/ang_vel", rr.Scalar(odom.twist.twist.angular.z))

# Update the robot pose itself via TF
self.log_tf_as_transform3d("map/robot", time)
Expand Down
2 changes: 1 addition & 1 deletion examples/python/face_tracking/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def is_empty(i): # type: ignore[no-untyped-def]

for blendshape in blendshapes:
if blendshape.category_name in BLENDSHAPES_CATEGORIES:
rr.log(f"blendshapes/{i}/{blendshape.category_name}", rr.TimeSeriesScalar(blendshape.score))
rr.log(f"blendshapes/{i}/{blendshape.category_name}", rr.Scalar(blendshape.score))


# ========================================================================================
Expand Down
49 changes: 27 additions & 22 deletions examples/python/plots/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@
### Time series
All other plots are created using the
[rr.TimeSeriesScalar archetype](https://www.rerun.io/docs/reference/types/archetypes/bar_chart)
with different settings. Each plot is created by logging scalars at different time steps (i.e., the x-axis).
[rr.Scalar archetype](https://www.rerun.io/docs/reference/types/archetypes/scalar?speculative-link)
archetype.
Each plot is created by logging scalars at different time steps (i.e., the x-axis).
Additionally, the plots are styled using the
[rr.SeriesLine](https://www.rerun.io/docs/reference/types/archetypes/series_line?speculative-link) and
[rr.SeriesPoint](https://www.rerun.io/docs/reference/types/archetypes/series_point?speculative-link)
archetypes respectively.
For the [parabola](recording://curves/parabola) the radius and color is changed over time.
For the [parabola](recording://curves/parabola) the radius and color is changed over time,
the other plots use timeless for their styling properties where possible.
[sin](recording://trig/sin) and [cos](recording://trig/cos) are logged with the same parent entity (i.e.,
`trig/{cos,sin}`) which will put them in the same view by default.
For the [classification samples](recording://classification/samples) `rr.TimeSeriesScalar(..., scatter=True)` is used to
create separate points that do not connect over time. Note, that in the other plots the logged scalars are connected
over time by lines.
""".strip()


Expand All @@ -59,12 +61,15 @@ def log_bar_chart() -> None:


def log_parabola() -> None:
# Name never changes, log it only once.
rr.log("curves/parabola", rr.SeriesLine(name="f(t) = (0.01t - 3)³ + 1"), timeless=True)

# Log a parabola as a time series
for t in range(0, 1000, 10):
rr.set_time_sequence("frame_nr", t)

f_of_t = (t * 0.01 - 5) ** 3 + 1
radius = clamp(abs(f_of_t) * 0.1, 0.5, 10.0)
width = clamp(abs(f_of_t) * 0.1, 0.5, 10.0)
color = [255, 255, 0]
if f_of_t < -10.0:
color = [255, 0, 0]
Expand All @@ -73,35 +78,35 @@ def log_parabola() -> None:

rr.log(
"curves/parabola",
rr.TimeSeriesScalar(
f_of_t,
label="f(t) = (0.01t - 3)³ + 1",
radius=radius,
color=color,
),
rr.Scalar(f_of_t),
rr.SeriesLine(width=width, color=color),
)


def log_trig() -> None:
# Log a time series
# Styling doesn't change over time, log it once with timeless=True.
rr.log("trig/sin", rr.SeriesLine(color=[255, 0, 0], name="sin(0.01t)"), timeless=True)
rr.log("trig/cos", rr.SeriesLine(color=[0, 255, 0], name="cos(0.01t)"), timeless=True)

for t in range(0, int(tau * 2 * 1000.0)):
rr.set_time_sequence("frame_nr", t)

sin_of_t = sin(float(t) / 1000.0)
rr.log("trig/sin", rr.TimeSeriesScalar(sin_of_t, label="sin(0.01t)", color=[255, 0, 0]))
rr.log("trig/sin", rr.Scalar(sin_of_t))

cos_of_t = cos(float(t) / 1000.0)
rr.log("trig/cos", rr.TimeSeriesScalar(cos_of_t, label="cos(0.01t)", color=[0, 255, 0]))
rr.log("trig/cos", rr.Scalar(cos_of_t))


def log_classification() -> None:
# Log a time series
# Log components that don't change only once:
rr.log("classification/line", rr.SeriesLine(color=[255, 255, 0], width=3.0), timeless=True)

for t in range(0, 1000, 2):
rr.set_time_sequence("frame_nr", t)

f_of_t = (2 * 0.01 * t) + 2
color = [255, 255, 0]
rr.log("classification/line", rr.TimeSeriesScalar(f_of_t, color=color, radius=3.0))
rr.log("classification/line", rr.Scalar(f_of_t))

g_of_t = f_of_t + random.uniform(-5.0, 5.0)
if g_of_t < f_of_t - 1.5:
Expand All @@ -110,8 +115,8 @@ def log_classification() -> None:
color = [0, 255, 0]
else:
color = [255, 255, 255]
radius = abs(g_of_t - f_of_t)
rr.log("classification/samples", rr.TimeSeriesScalar(g_of_t, color=color, scattered=True, radius=radius))
marker_size = abs(g_of_t - f_of_t)
rr.log("classification/samples", rr.Scalar(g_of_t), rr.SeriesPoint(color=color, marker_size=marker_size))


def main() -> None:
Expand Down
4 changes: 2 additions & 2 deletions examples/python/ros_node/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ def odom_callback(self, odom: Odometry) -> None:
rr.set_time_nanos("ros_time", time.nanoseconds)

# Capture time-series data for the linear and angular velocities
rr.log("odometry/vel", rr.TimeSeriesScalar(odom.twist.twist.linear.x))
rr.log("odometry/ang_vel", rr.TimeSeriesScalar(odom.twist.twist.angular.z))
rr.log("odometry/vel", rr.Scalar(odom.twist.twist.linear.x))
rr.log("odometry/ang_vel", rr.Scalar(odom.twist.twist.angular.z))

# Update the robot pose itself via TF
self.log_tf_as_transform3d("map/robot", time)
Expand Down
5 changes: 3 additions & 2 deletions examples/python/structure_from_motion/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
[camera entity](recording://camera).
### Reprojection error
For each image a [rr.TimeSeriesScalar archetype](https://www.rerun.io/docs/reference/types/archetypes/bar_chart)
For each image a [rr.Scalar archetype](https://www.rerun.io/docs/reference/types/archetypes/scalar?speculative-link)
containing the average reprojection error of the keypoints is logged to the
[plot/avg_reproj_err entity](recording://plot/avg_reproj_err).
Expand Down Expand Up @@ -134,6 +134,7 @@ def read_and_log_sparse_reconstruction(dataset_path: Path, filter_output: bool,

rr.log("description", rr.TextDocument(DESCRIPTION, media_type=rr.MediaType.MARKDOWN), timeless=True)
rr.log("/", rr.ViewCoordinates.RIGHT_HAND_Y_DOWN, timeless=True)
rr.log("plot/avg_reproj_err", rr.SeriesLine(color=[240, 45, 58]), timeless=True)

# Iterate through images (video frames) logging data related to each frame.
for image in sorted(images.values(), key=lambda im: im.name): # type: ignore[no-any-return]
Expand Down Expand Up @@ -171,7 +172,7 @@ def read_and_log_sparse_reconstruction(dataset_path: Path, filter_output: bool,
point_colors = [point.rgb for point in visible_xyzs]
point_errors = [point.error for point in visible_xyzs]

rr.log("plot/avg_reproj_err", rr.TimeSeriesScalar(np.mean(point_errors), color=[240, 45, 58]))
rr.log("plot/avg_reproj_err", rr.Scalar(np.mean(point_errors)))

rr.log("points", rr.Points3D(points, colors=point_colors), rr.AnyValues(error=point_errors))

Expand Down
3 changes: 2 additions & 1 deletion rerun_cpp/src/rerun/archetypes/scalar.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion rerun_cpp/src/rerun/archetypes/time_series_scalar.hpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b9cd458

Please sign in to comment.