Skip to content

Commit 31d5943

Browse files
authored
Dataframe v2: examples (#7817)
Full standalone Rust & Python examples for people who like to learn by jumping straight into the examples/ folder. Simpler snippets and the associated reference page are coming in a future PR.
1 parent 6d86699 commit 31d5943

File tree

10 files changed

+557
-333
lines changed

10 files changed

+557
-333
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,6 +1711,15 @@ version = "2.5.0"
17111711
source = "registry+https://github.com/rust-lang/crates.io-index"
17121712
checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
17131713

1714+
[[package]]
1715+
name = "dataframe_query"
1716+
version = "0.19.0-alpha.7"
1717+
dependencies = [
1718+
"itertools 0.13.0",
1719+
"rerun",
1720+
"unindent",
1721+
]
1722+
17141723
[[package]]
17151724
name = "deranged"
17161725
version = "0.3.11"

examples/manifest.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,13 @@ examples = [
152152
# or explicitly excluded by running `python scripts/check_example_manifest_coverage.py`.
153153
[ignored]
154154
examples = [
155+
"_empty_rerun_sdk",
156+
"all_examples",
155157
"custom_collection_adapter",
156158
"custom_data_loader",
157159
"custom_space_view",
158160
"custom_store_subscriber",
161+
"dataframe_query",
159162
"drone_lidar",
160163
"extend_viewer_ui",
161164
"external_data_loader",
@@ -165,6 +168,4 @@ examples = [
165168
"spawn_viewer",
166169
"stdio",
167170
"template",
168-
"all_examples",
169-
"_empty_rerun_sdk",
170171
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
This example will query for the first 10 rows of data in your recording of choice,
2+
and display the results as a table in your terminal.
3+
4+
You can use one of your recordings, or grab one from our hosted examples, e.g.:
5+
```bash
6+
curl 'https://app.rerun.io/version/latest/examples/dna.rrd' -o - > /tmp/dna.rrd
7+
```
8+
9+
The results can be filtered further by specifying an entity filter expression:
10+
```bash
11+
python dataframe_query.py my_recording.rrd /helix/structure/**\
12+
```
13+
14+
```bash
15+
python dataframe_query.py <path_to_rrd> [entity_path_filter]
16+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python3
2+
"""Demonstrates basic usage of the dataframe APIs."""
3+
4+
from __future__ import annotations
5+
6+
import argparse
7+
8+
import pyarrow as pa
9+
import rerun as rr
10+
11+
DESCRIPTION = """
12+
Usage: python dataframe_query.py <path_to_rrd> [entity_path_filter]
13+
14+
This example will query for the first 10 rows of data in your recording of choice,
15+
and display the results as a table in your terminal.
16+
17+
You can use one of your recordings, or grab one from our hosted examples, e.g.:
18+
curl 'https://app.rerun.io/version/latest/examples/dna.rrd' -o - > /tmp/dna.rrd
19+
20+
The results can be filtered further by specifying an entity filter expression:
21+
{bin_name} my_recording.rrd /helix/structure/**
22+
""".strip()
23+
24+
25+
def query(path_to_rrd: str, entity_path_filter: str) -> None:
26+
recording = rr.dataframe.load_recording(path_to_rrd)
27+
view = recording.view(index="log_time", contents=entity_path_filter)
28+
batches = view.select()
29+
30+
table = pa.Table.from_batches(batches, batches.schema)
31+
table = table.slice(0, 10)
32+
print(table.to_pandas())
33+
34+
35+
def main() -> None:
36+
parser = argparse.ArgumentParser(description=DESCRIPTION)
37+
parser.add_argument("path_to_rrd", type=str, help="Path to the .rrd file")
38+
parser.add_argument(
39+
"entity_path_filter", type=str, nargs="?", default="/**", help="Optional entity path filter expression"
40+
)
41+
args = parser.parse_args()
42+
43+
query(args.path_to_rrd, args.entity_path_filter)
44+
45+
46+
if __name__ == "__main__":
47+
main()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[project]
2+
name = "dataframe_query"
3+
version = "0.1.0"
4+
# requires-python = "<3.12"
5+
readme = "README.md"
6+
dependencies = ["rerun-sdk"]
7+
8+
[project.scripts]
9+
dataframe_query = "dataframe_query:main"
10+
11+
[build-system]
12+
requires = ["hatchling"]
13+
build-backend = "hatchling.build"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "dataframe_query"
3+
version = "0.19.0-alpha.7"
4+
edition = "2021"
5+
rust-version = "1.79"
6+
license = "MIT OR Apache-2.0"
7+
publish = false
8+
9+
[dependencies]
10+
rerun = { path = "../../../crates/top/rerun", default-features = false, features = [
11+
"dataframe",
12+
] }
13+
14+
itertools = "0.13"
15+
unindent = "0.2"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
This example will query for the first 10 rows of data in your recording of choice,
2+
and display the results as a table in your terminal.
3+
4+
```bash
5+
cargo run --release -- <path_to_rrd> [entity_path_filter]
6+
```
7+
8+
You can use one of your recordings, or grab one from our hosted examples, e.g.:
9+
```bash
10+
curl 'https://app.rerun.io/version/latest/examples/dna.rrd' -o - > /tmp/dna.rrd
11+
```
12+
13+
The results can be filtered further by specifying an entity filter expression:
14+
```bash
15+
cargo run --release -- my_recording.rrd /helix/structure/**\
16+
```
17+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//! Demonstrates basic usage of the dataframe APIs.
2+
3+
use itertools::Itertools;
4+
5+
use rerun::{
6+
dataframe::{
7+
concatenate_record_batches, EntityPathFilter, QueryCache, QueryEngine, QueryExpression,
8+
SparseFillStrategy, Timeline,
9+
},
10+
ChunkStore, ChunkStoreConfig, StoreKind, VersionPolicy,
11+
};
12+
13+
fn main() -> Result<(), Box<dyn std::error::Error>> {
14+
let args = std::env::args().collect_vec();
15+
16+
let get_arg = |i| {
17+
let Some(value) = args.get(i) else {
18+
let bin_name = args.first().map_or("$BIN", |s| s.as_str());
19+
eprintln!(
20+
"{}",
21+
unindent::unindent(&format!(
22+
"\
23+
Usage: {bin_name} <path_to_rrd> [entity_path_filter]
24+
25+
This example will query for the first 10 rows of data in your recording of choice,
26+
and display the results as a table in your terminal.
27+
28+
You can use one of your recordings, or grab one from our hosted examples, e.g.:
29+
curl 'https://app.rerun.io/version/latest/examples/dna.rrd' -o - > /tmp/dna.rrd
30+
31+
The results can be filtered further by specifying an entity filter expression:
32+
{bin_name} my_recording.rrd /helix/structure/**\
33+
",
34+
)),
35+
);
36+
std::process::exit(1);
37+
};
38+
value
39+
};
40+
41+
let path_to_rrd = get_arg(1);
42+
let entity_path_filter = EntityPathFilter::try_from(args.get(2).map_or("/**", |s| s.as_str()))?;
43+
let timeline = Timeline::log_time();
44+
45+
let stores = ChunkStore::from_rrd_filepath(
46+
&ChunkStoreConfig::DEFAULT,
47+
path_to_rrd,
48+
VersionPolicy::Warn,
49+
)?;
50+
51+
for (store_id, store) in &stores {
52+
if store_id.kind != StoreKind::Recording {
53+
continue;
54+
}
55+
56+
let query_cache = QueryCache::new(store);
57+
let query_engine = QueryEngine {
58+
store,
59+
cache: &query_cache,
60+
};
61+
62+
let query = QueryExpression {
63+
filtered_index: Some(timeline),
64+
view_contents: Some(
65+
query_engine
66+
.iter_entity_paths(&entity_path_filter)
67+
.map(|entity_path| (entity_path, None))
68+
.collect(),
69+
),
70+
sparse_fill_strategy: SparseFillStrategy::LatestAtGlobal,
71+
..Default::default()
72+
};
73+
74+
let query_handle = query_engine.query(query.clone());
75+
let record_batches = query_handle.batch_iter().take(10).collect_vec();
76+
77+
let table = concatenate_record_batches(query_handle.schema().clone(), &record_batches)?;
78+
println!("{table}");
79+
}
80+
81+
Ok(())
82+
}

0 commit comments

Comments
 (0)