chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<!--[metadata]
|
||||
title = "Plots"
|
||||
tags = ["2D", "Plots", "API example"]
|
||||
thumbnail = "https://static.rerun.io/plots/e8e51071f6409f61dc04a655d6b9e1caf8179226/480w.png"
|
||||
thumbnail_dimensions = [480, 480]
|
||||
channel = "main"
|
||||
include_in_manifest = true
|
||||
-->
|
||||
|
||||
This example demonstrates how to log simple plots with the Rerun SDK. Charts can be created from 1-dimensional tensors, or from time-varying scalars.
|
||||
|
||||
<picture data-inline-viewer="examples/plots">
|
||||
<source media="(max-width: 480px)" srcset="https://static.rerun.io/plots/c5b91cf0bf2eaf91c71d6cdcd4fe312d4aeac572/480w.png">
|
||||
<source media="(max-width: 768px)" srcset="https://static.rerun.io/plots/c5b91cf0bf2eaf91c71d6cdcd4fe312d4aeac572/768w.png">
|
||||
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/plots/c5b91cf0bf2eaf91c71d6cdcd4fe312d4aeac572/1024w.png">
|
||||
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/plots/c5b91cf0bf2eaf91c71d6cdcd4fe312d4aeac572/1200w.png">
|
||||
<img src="https://static.rerun.io/plots/c5b91cf0bf2eaf91c71d6cdcd4fe312d4aeac572/full.png" alt="Plots example screenshot">
|
||||
</picture>
|
||||
|
||||
## Used Rerun types
|
||||
|
||||
[`BarChart`](https://www.rerun.io/docs/reference/types/archetypes/bar_chart), [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars), [`SeriesPoints`](https://www.rerun.io/docs/reference/types/archetypes/series_points), [`SeriesLines`](https://www.rerun.io/docs/reference/types/archetypes/series_lines), [`TextDocument`](https://www.rerun.io/docs/reference/types/archetypes/text_document)
|
||||
|
||||
## Logging and visualizing with Rerun
|
||||
|
||||
This example shows various plot types that you can create using Rerun. Common usecases for such plots would be logging
|
||||
losses or metrics over time, histograms, or general function plots.
|
||||
|
||||
The bar chart is created by logging the [`BarChart`](https://www.rerun.io/docs/reference/types/archetypes/bar_chart) archetype.
|
||||
All other plots are created using the [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars) archetype.
|
||||
Each plot is created by logging scalars at different time steps (i.e., the x-axis).
|
||||
Additionally, the plots are styled using the [`SeriesLines`](https://www.rerun.io/docs/reference/types/archetypes/series_lines) and
|
||||
[`SeriesPoints`](https://www.rerun.io/docs/reference/types/archetypes/series_points) archetypes respectively.
|
||||
|
||||
The visualizations in this example were created with the following Rerun code:
|
||||
|
||||
### Bar chart
|
||||
|
||||
The `log_bar_chart` function logs a bar chat.
|
||||
It generates data for a Gaussian bell curve and logs it using [`BarChart`](https://www.rerun.io/docs/reference/types/archetypes/bar_chart) archetype.
|
||||
```python
|
||||
def log_bar_chart() -> None:
|
||||
# … existing code …
|
||||
rr.log("bar_chart", rr.BarChart(y))
|
||||
```
|
||||
|
||||
### Curves
|
||||
The `log_parabola` function logs a parabola curve (sine and cosine functions) as a time series.
|
||||
|
||||
It first sets up a time sequence using [`timelines`](https://www.rerun.io/docs/concepts/logging-and-ingestion/timelines), then calculates the y-value of the parabola at each time step, and logs it using [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars) archetype.
|
||||
It also adjusts the width and color of the plotted line based on the calculated y value using [`SeriesLines`](https://www.rerun.io/docs/reference/types/archetypes/series_lines) archetype.
|
||||
|
||||
```python
|
||||
def log_parabola() -> None:
|
||||
# Name never changes, log it only once.
|
||||
rr.log("curves/parabola", rr.SeriesLines(name="f(t) = (0.01t - 3)³ + 1"), static=True)
|
||||
|
||||
# Log a parabola as a time series
|
||||
for t in range(0, 1000, 10):
|
||||
rr.set_time("frame_nr", sequence=t)
|
||||
|
||||
# … existing code …
|
||||
|
||||
rr.log(
|
||||
"curves/parabola",
|
||||
rr.Scalars(f_of_t),
|
||||
rr.SeriesLines(width=width, color=color),
|
||||
)
|
||||
```
|
||||
|
||||
### Trig
|
||||
|
||||
The `log_trig` function logs sin and cos functions as time series. Sin and cos are logged with the same parent entity (i.e.,`trig/{cos,sin}`) which will put them in the same view by default.
|
||||
|
||||
It first logs the styling properties of the sin and cos plots using [`SeriesLines`](https://www.rerun.io/docs/reference/types/archetypes/series_lines) archetype.
|
||||
Then, it iterates over a range of time steps, calculates the sin and cos values at each time step, and logs them using [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars) archetype.
|
||||
|
||||
```python
|
||||
def log_trig() -> None:
|
||||
# Styling doesn't change over time, log it once with static=True.
|
||||
rr.log("trig/sin", rr.SeriesLines(color=[255, 0, 0], name="sin(0.01t)"), static=True)
|
||||
rr.log("trig/cos", rr.SeriesLines(color=[0, 255, 0], name="cos(0.01t)"), static=True)
|
||||
|
||||
for t in range(0, int(tau * 2 * 100.0)):
|
||||
rr.set_time("frame_nr", sequence=t)
|
||||
|
||||
sin_of_t = sin(float(t) / 100.0)
|
||||
rr.log("trig/sin", rr.Scalars(sin_of_t))
|
||||
|
||||
cos_of_t = cos(float(t) / 100.0)
|
||||
rr.log("trig/cos", rr.Scalars(cos_of_t))
|
||||
```
|
||||
|
||||
### Classification
|
||||
|
||||
The `log_classification` function simulates a classification problem by logging a line function and randomly generated samples around that line.
|
||||
|
||||
It first logs the styling properties of the line plot using [`SeriesLines`](https://www.rerun.io/docs/reference/types/archetypes/series_lines) archetype.
|
||||
Then, it iterates over a range of time steps, calculates the y value of the line function at each time step, and logs it as a scalars using [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars) archetype.
|
||||
Additionally, it generates random samples around the line function and logs them using [`Scalars`](https://www.rerun.io/docs/reference/types/archetypes/scalars) and [`SeriesPoints`](https://www.rerun.io/docs/reference/types/archetypes/series_points) archetypes.
|
||||
|
||||
```python
|
||||
def log_classification() -> None:
|
||||
# Log components that don't change only once:
|
||||
rr.log("classification/line", rr.SeriesLines(colors=[255, 255, 0], widths=3.0), static=True)
|
||||
|
||||
for t in range(0, 1000, 2):
|
||||
rr.set_time("frame_nr", sequence=t)
|
||||
|
||||
# … existing code …
|
||||
rr.log("classification/line", rr.Scalars(f_of_t))
|
||||
|
||||
# … existing code …
|
||||
rr.log("classification/samples", rr.Scalars(g_of_t), rr.SeriesPoints(colors=color, marker_sizes=marker_size))
|
||||
```
|
||||
|
||||
|
||||
## Run the code
|
||||
To run this example, make sure you have the Rerun repository checked out and the latest SDK installed:
|
||||
```bash
|
||||
pip install --upgrade rerun-sdk # install the latest Rerun SDK
|
||||
git clone git@github.com:rerun-io/rerun.git # Clone the repository
|
||||
cd rerun
|
||||
git checkout latest # Check out the commit matching the latest SDK release
|
||||
```
|
||||
Install the necessary libraries specified in the requirements file:
|
||||
```bash
|
||||
pip install -e examples/python/plots
|
||||
```
|
||||
To experiment with the provided example, simply execute the main Python script:
|
||||
```bash
|
||||
python -m plots # run the example
|
||||
```
|
||||
If you wish to customize it, explore additional features, or save it use the CLI with the `--help` option for guidance:
|
||||
```bash
|
||||
python -m plots --help
|
||||
```
|
||||
|
||||
## Advanced time series - [`send_columns`](https://ref.rerun.io/docs/python/stable/common/columnar_api/#rerun.send_columns)
|
||||
Logging many scalars individually can be slow.
|
||||
The [`send_columns`](https://ref.rerun.io/docs/python/stable/common/columnar_api/#rerun.send_columns) API can be used to log many scalars at once.
|
||||
Check the [`Scalars` `send_columns` snippet](https://rerun.io/docs/reference/types/archetypes/scalars#update-a-scalar-over-time-in-a-single-operation) to learn more.
|
||||
Executable
+182
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Demonstrates how to log simple plots with the Rerun SDK.
|
||||
|
||||
Run:
|
||||
```sh
|
||||
./examples/python/plot/plots.py
|
||||
```
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import random
|
||||
from math import cos, sin, tau
|
||||
|
||||
import numpy as np
|
||||
|
||||
import rerun as rr
|
||||
import rerun.blueprint as rrb
|
||||
|
||||
DESCRIPTION = """
|
||||
# Plots
|
||||
This example shows various plot types that you can create using Rerun. Common usecases for such plots would be logging
|
||||
losses or metrics over time, histograms, or general function plots.
|
||||
|
||||
The full source code for this example is available [on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/plots).
|
||||
""".strip()
|
||||
|
||||
|
||||
def log_bar_chart() -> None:
|
||||
rr.set_time("frame_nr", sequence=0)
|
||||
# Log a gauss bell as a bar chart
|
||||
mean = 0
|
||||
std = 1
|
||||
variance = np.square(std)
|
||||
x = np.arange(-5, 5, 0.1)
|
||||
y = np.exp(-np.square(x - mean) / 2 * variance) / (np.sqrt(2 * np.pi * variance))
|
||||
rr.log("bar_chart", rr.BarChart(y))
|
||||
|
||||
|
||||
def log_parabola() -> None:
|
||||
# Time-independent styling can be achieved by logging static components to the data store. Here, by using the
|
||||
# `SeriesLines` archetype, we further hint the viewer to use the line plot visualizer.
|
||||
# Alternatively, you can achieve time-independent styling using overrides, as is everywhere else in this example
|
||||
# (see the `main()` function).
|
||||
rr.log("curves/parabola", rr.SeriesLines(names="f(t) = (0.01t - 3)³ + 1"), static=True)
|
||||
|
||||
# Log a parabola as a time series
|
||||
for t in range(0, 1000, 10):
|
||||
rr.set_time("frame_nr", sequence=t)
|
||||
|
||||
f_of_t = (t * 0.01 - 5) ** 3 + 1
|
||||
width = np.clip(abs(f_of_t) * 0.1, 0.5, 10.0)
|
||||
color = [255, 255, 0]
|
||||
if f_of_t < -10.0:
|
||||
color = [255, 0, 0]
|
||||
elif f_of_t > 10.0:
|
||||
color = [0, 255, 0]
|
||||
|
||||
# Note: by using the `rr.SeriesLines` archetype, we hint the viewer to use the line plot visualizer.
|
||||
rr.log(
|
||||
"curves/parabola",
|
||||
rr.Scalars(f_of_t),
|
||||
rr.SeriesLines(widths=width, colors=color),
|
||||
)
|
||||
|
||||
|
||||
def log_trig() -> None:
|
||||
for t in range(int(tau * 2 * 100.0)):
|
||||
rr.set_time("frame_nr", sequence=t)
|
||||
|
||||
sin_of_t = sin(float(t) / 100.0)
|
||||
rr.log("trig/sin", rr.Scalars(sin_of_t))
|
||||
|
||||
cos_of_t = cos(float(t) / 100.0)
|
||||
rr.log("trig/cos", rr.Scalars(cos_of_t))
|
||||
|
||||
|
||||
def log_spiral() -> None:
|
||||
times = np.arange(int(tau * 2 * 100.0))
|
||||
theta = times / 100.0
|
||||
|
||||
x = theta * np.cos(theta)
|
||||
y = theta * np.sin(theta)
|
||||
|
||||
# want this in column major, and numpy is row-major by default
|
||||
scalars = np.array((x, y)).T
|
||||
rr.send_columns(
|
||||
"spiral",
|
||||
indexes=[rr.TimeColumn("frame_nr", sequence=times)],
|
||||
columns=[*rr.Scalars.columns(scalars=scalars)],
|
||||
)
|
||||
|
||||
|
||||
def log_classification() -> None:
|
||||
for t in range(0, 1000, 2):
|
||||
rr.set_time("frame_nr", sequence=t)
|
||||
|
||||
f_of_t = (2 * 0.01 * t) + 2
|
||||
rr.log("classification/line", rr.Scalars(f_of_t))
|
||||
|
||||
g_of_t = f_of_t + random.uniform(-5.0, 5.0)
|
||||
if g_of_t < f_of_t - 1.5:
|
||||
color = [255, 0, 0]
|
||||
elif g_of_t > f_of_t + 1.5:
|
||||
color = [0, 255, 0]
|
||||
else:
|
||||
color = [255, 255, 255]
|
||||
marker_size = abs(g_of_t - f_of_t)
|
||||
|
||||
# Note: this log call doesn't include any hint as to which visualizer to use. We use a blueprint visualizer
|
||||
# override instead (see `main()`)
|
||||
rr.log(
|
||||
"classification/samples",
|
||||
rr.Scalars(g_of_t),
|
||||
rr.SeriesPoints(colors=color, marker_sizes=marker_size),
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="demonstrates how to integrate python's native `logging` with the Rerun SDK",
|
||||
)
|
||||
rr.script_add_args(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
blueprint = rrb.Blueprint(
|
||||
rrb.Horizontal(
|
||||
rrb.Vertical(
|
||||
rrb.Grid(
|
||||
rrb.BarChartView(name="Bar Chart", origin="/bar_chart"),
|
||||
rrb.TimeSeriesView(
|
||||
name="Curves",
|
||||
origin="/curves",
|
||||
),
|
||||
rrb.TimeSeriesView(
|
||||
name="Trig",
|
||||
origin="/trig",
|
||||
overrides={
|
||||
"/trig/sin": rr.SeriesLines.from_fields(colors=[255, 0, 0], names="sin(0.01t)"),
|
||||
"/trig/cos": rr.SeriesLines.from_fields(colors=[0, 255, 0], names="cos(0.01t)"),
|
||||
},
|
||||
),
|
||||
rrb.TimeSeriesView(
|
||||
name="Classification",
|
||||
origin="/classification",
|
||||
overrides={
|
||||
"classification/line": rr.SeriesLines.from_fields(colors=[255, 255, 0], widths=3.0),
|
||||
# This ensures that the `SeriesPoints` visualizers is used for this entity.
|
||||
"classification/samples": rr.SeriesPoints(),
|
||||
},
|
||||
),
|
||||
),
|
||||
rrb.TimeSeriesView(
|
||||
name="Spiral",
|
||||
origin="/spiral",
|
||||
overrides={"spiral": rr.SeriesLines.from_fields(names=["0.01t cos(0.01t)", "0.01t sin(0.01t)"])}, # type: ignore[arg-type]
|
||||
),
|
||||
row_shares=[2, 1],
|
||||
),
|
||||
rrb.TextDocumentView(name="Description", origin="/description"),
|
||||
column_shares=[3, 1],
|
||||
),
|
||||
rrb.SelectionPanel(state="collapsed"),
|
||||
rrb.TimePanel(state="collapsed"),
|
||||
)
|
||||
|
||||
rr.script_setup(args, "rerun_example_plot", default_blueprint=blueprint)
|
||||
|
||||
rr.log("description", rr.TextDocument(DESCRIPTION, media_type=rr.MediaType.MARKDOWN), static=True)
|
||||
log_bar_chart()
|
||||
log_parabola()
|
||||
log_trig()
|
||||
log_spiral()
|
||||
log_classification()
|
||||
|
||||
rr.script_teardown(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,13 @@
|
||||
[project]
|
||||
name = "plots"
|
||||
version = "0.1.0"
|
||||
readme = "README.md"
|
||||
dependencies = ["numpy", "rerun-sdk"]
|
||||
|
||||
[project.scripts]
|
||||
plots = "plots:main"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
Reference in New Issue
Block a user