From 086e10d1f0827918522ad245dbf71b3630e59a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Wed, 11 Dec 2024 17:13:55 +0100 Subject: [PATCH 01/12] Promote time-varying layout to full example --- examples/manifest.toml | 4 +- .../python/graph_lattice/graph_lattice.py | 72 ------ .../{graph_lattice => graphs}/README.md | 20 +- examples/python/graphs/graphs.py | 206 ++++++++++++++++++ .../{graph_lattice => graphs}/pyproject.toml | 4 +- pixi.lock | 44 ++-- pixi.toml | 2 +- .../check_graph_time_layout.py | 111 ---------- 8 files changed, 243 insertions(+), 220 deletions(-) delete mode 100644 examples/python/graph_lattice/graph_lattice.py rename examples/python/{graph_lattice => graphs}/README.md (55%) create mode 100644 examples/python/graphs/graphs.py rename examples/python/{graph_lattice => graphs}/pyproject.toml (74%) delete mode 100644 tests/python/release_checklist/check_graph_time_layout.py diff --git a/examples/manifest.toml b/examples/manifest.toml index 915fc0509dcf..5be17e03604d 100644 --- a/examples/manifest.toml +++ b/examples/manifest.toml @@ -142,6 +142,7 @@ examples = [ "notebook", "clock", "dna", + "graphs", "log_file", "openstreetmap_data", "minimal", @@ -150,8 +151,6 @@ examples = [ "plots", "live_scrolling_plot", "raw_mesh", - "graph_lattice", - "graph_binary_tree", "air_traffic_data", ] @@ -169,6 +168,7 @@ examples = [ "drone_lidar", "extend_viewer_ui", "external_data_loader", + "graph_binary_tree", "incremental_logging", "minimal_serve", "shared_recording", diff --git a/examples/python/graph_lattice/graph_lattice.py b/examples/python/graph_lattice/graph_lattice.py deleted file mode 100644 index 21eb327df1ca..000000000000 --- a/examples/python/graph_lattice/graph_lattice.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 -"""Examples of logging graph data to Rerun and performing a force-based layout.""" - -from __future__ import annotations - -import argparse -import itertools - -import rerun as rr - -NUM_NODES = 10 - -DESCRIPTION = """ -# Graph Lattice -This is a minimal example that logs a graph (node-link diagram) that represents a lattice. - -In this example, the node positions—and therefore the graph layout—are computed by Rerun internally. - -The full source code for this example is available -[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graph_lattice?speculative-link). -""".strip() - - -def log_data() -> None: - rr.log("description", rr.TextDocument(DESCRIPTION, media_type=rr.MediaType.MARKDOWN), static=True) - - coordinates = itertools.product(range(NUM_NODES), range(NUM_NODES)) - - nodes, colors = zip(*[ - ( - str(i), - rr.components.Color([round((x / (NUM_NODES - 1)) * 255), round((y / (NUM_NODES - 1)) * 255), 0]), - ) - for i, (x, y) in enumerate(coordinates) - ]) - - rr.log( - "/lattice", - rr.GraphNodes( - nodes, - colors=colors, - labels=[f"({x}, {y})" for x, y in itertools.product(range(NUM_NODES), range(NUM_NODES))], - ), - static=True, - ) - - edges = [] - for x, y in itertools.product(range(NUM_NODES), range(NUM_NODES)): - if y > 0: - source = (y - 1) * NUM_NODES + x - target = y * NUM_NODES + x - edges.append((str(source), str(target))) - if x > 0: - source = y * NUM_NODES + (x - 1) - target = y * NUM_NODES + x - edges.append((str(source), str(target))) - - rr.log("/lattice", rr.GraphEdges(edges, graph_type="directed"), static=True) - - -def main() -> None: - parser = argparse.ArgumentParser(description="Logs a graph lattice using the Rerun SDK.") - rr.script_add_args(parser) - args = parser.parse_args() - - rr.script_setup(args, "rerun_example_graph_lattice") - log_data() - rr.script_teardown(args) - - -if __name__ == "__main__": - main() diff --git a/examples/python/graph_lattice/README.md b/examples/python/graphs/README.md similarity index 55% rename from examples/python/graph_lattice/README.md rename to examples/python/graphs/README.md index ed764409c37c..245143a18cc0 100644 --- a/examples/python/graph_lattice/README.md +++ b/examples/python/graphs/README.md @@ -1,8 +1,8 @@ @@ -10,11 +10,11 @@ This example shows different attributes that you can associate with nodes in a g Since no explicit positions are passed for the nodes, Rerun will layout the graph automatically. - - - - - + + + + + ## Used Rerun types @@ -24,6 +24,6 @@ Since no explicit positions are passed for the nodes, Rerun will layout the grap ## Run the code ```bash -pip install -e examples/python/graph_lattice -python -m graph_lattice +pip install -e examples/python/graphs +python -m graphs ``` diff --git a/examples/python/graphs/graphs.py b/examples/python/graphs/graphs.py new file mode 100644 index 000000000000..671a31a62fe8 --- /dev/null +++ b/examples/python/graphs/graphs.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +"""Examples of logging graph data to Rerun and performing force-based layouts.""" + +from __future__ import annotations + +import argparse +import random +import itertools +import numpy as np + +import rerun as rr +import rerun.blueprint as rrb + +from rerun.blueprint.archetypes.force_collision_radius import ForceCollisionRadius +from rerun.blueprint.archetypes.force_link import ForceLink +from rerun.blueprint.archetypes.force_many_body import ForceManyBody +from rerun.components.color import Color +from rerun.components.radius import Radius +from rerun.components.show_labels import ShowLabels + + +color_scheme = [ + Color([228, 26, 28]), # Red + Color([55, 126, 184]), # Blue + Color([77, 175, 74]), # Green + Color([152, 78, 163]), # Purple + Color([255, 127, 0]), # Orange + Color([255, 255, 51]), # Yellow + Color([166, 86, 40]), # Brown + Color([247, 129, 191]), # Pink + Color([153, 153, 153]), # Gray +] + +DESCRIPTION = """ +# Graphs +This example shows various graph visualizations that you can create using Rerun. +In this example, the node positions—and therefore the graph layout—are computed by Rerun internally using a force-based layout algorithm. + +You can modify how these graphs look by changing the parameters of the force-based layout algorithm in the selection panel. + +The full source code for this example is available +[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graphs?speculative-link). +""".strip() + + +# We want reproducible results +random.seed(42) + + +def log_lattice(num_nodes) -> None: + coordinates = itertools.product(range(num_nodes), range(num_nodes)) + + nodes, colors = zip(*[ + ( + str(i), + rr.components.Color([round((x / (num_nodes - 1)) * 255), round((y / (num_nodes - 1)) * 255), 0]), + ) + for i, (x, y) in enumerate(coordinates) + ]) + + rr.log( + "lattice", + rr.GraphNodes( + nodes, + colors=colors, + labels=[f"({x}, {y})" for x, y in itertools.product(range(num_nodes), range(num_nodes))], + ), + static=True, + ) + + edges = [] + for x, y in itertools.product(range(num_nodes), range(num_nodes)): + if y > 0: + source = (y - 1) * num_nodes + x + target = y * num_nodes + x + edges.append((str(source), str(target))) + if x > 0: + source = y * num_nodes + (x - 1) + target = y * num_nodes + x + edges.append((str(source), str(target))) + + rr.log("/lattice", rr.GraphEdges(edges, graph_type="directed"), static=True) + + +def log_trees() -> None: + nodes = ["root"] + radii = [42] + colors = [Color([81, 81, 81])] + edges = [] + + # Randomly add nodes and edges to the graph + for i in range(50): + existing = random.choice(nodes) + new_node = str(i) + nodes.append(new_node) + radii.append(random.randint(10, 50)) + colors.append(random.choice(color_scheme)) + edges.append((existing, new_node)) + + rr.set_time_sequence("frame", i) + rr.log( + "node_link", + rr.GraphNodes(nodes, labels=nodes, radii=radii, colors=colors), + rr.GraphEdges(edges, graph_type=rr.GraphType.Directed), + ) + rr.log( + "bubble_chart", + rr.GraphNodes(nodes, labels=nodes, radii=radii, colors=colors), + ) + + +def log_markov_chain() -> None: + transition_matrix = np.array([ + [0.8, 0.1, 0.1], # Transitions from sunny + [0.3, 0.4, 0.3], # Transitions from rainy + [0.2, 0.3, 0.5], # Transitions from cloudy + ]) + state_names = ["sunny", "rainy", "cloudy"] + # For this example, we use hardcoded positions. + positions = [[0, 0], [150, 150], [300, 0]] + inactive_color = Color([153, 153, 153]) # Gray + active_colors = [ + Color([255, 127, 0]), # Orange + Color([55, 126, 184]), # Blue + Color([152, 78, 163]), # Purple + ] + + edges = [(state_names[i], state_names[j]) for i in range(len(state_names)) for j in range(len(state_names)) if transition_matrix[i][j] > 0] + + # We start in state "sunny" + state = "sunny" + + for i in range(50): + current_state_index = state_names.index(state) + next_state_index = np.random.choice( + range(len(state_names)), p=transition_matrix[current_state_index] + ) + state = state_names[next_state_index] + colors = [inactive_color] * len(state_names) + colors[next_state_index] = active_colors[next_state_index] + + print(colors) + + rr.set_time_sequence("frame", i) + rr.log( + "markov_chain", + rr.GraphNodes(state_names, labels=state_names, colors=colors, positions=positions), + rr.GraphEdges(edges, graph_type="directed") + ) + + + +def log_blueprint() -> None: + rr.send_blueprint( + rrb.Blueprint( + rrb.Grid( + rrb.GraphView( + origin="node_link", + name="Node-link diagram", + force_link=ForceLink(distance=60), + force_many_body=ForceManyBody(strength=-60), + ), + rrb.GraphView( + origin="bubble_chart", + name="Bubble chart", + force_link=ForceLink(enabled=False), + force_many_body=ForceManyBody(enabled=False), + force_collision_radius=ForceCollisionRadius(enabled=True), + defaults=[ShowLabels(False)], + ), + rrb.GraphView( + origin="lattice", + name="Lattice", + force_link=ForceLink(distance=60), + force_many_body=ForceManyBody(strength=-60), + defaults=[ShowLabels(False), Radius(10)], + ), + rrb.Horizontal( + rrb.GraphView( + origin="markov_chain", + name="Markov Chain", + # We don't need any forces for this graph, because the nodes have fixed positions. + ), + rrb.TextDocumentView(origin="description", name="Description"), + ) + ) + ) + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description="Logs various graphs using the Rerun SDK.") + rr.script_add_args(parser) + args = parser.parse_args() + + rr.script_setup(args, "rerun_example_graphs") + rr.log("description", rr.TextDocument(DESCRIPTION, media_type=rr.MediaType.MARKDOWN), static=True) + log_trees() + log_lattice(10) + log_markov_chain() + log_blueprint() + rr.script_teardown(args) + + +if __name__ == "__main__": + main() diff --git a/examples/python/graph_lattice/pyproject.toml b/examples/python/graphs/pyproject.toml similarity index 74% rename from examples/python/graph_lattice/pyproject.toml rename to examples/python/graphs/pyproject.toml index 128b7879d28e..107c5d05bba6 100644 --- a/examples/python/graph_lattice/pyproject.toml +++ b/examples/python/graphs/pyproject.toml @@ -1,11 +1,11 @@ [project] -name = "graph_lattice" +name = "graphs" version = "0.1.0" readme = "README.md" dependencies = ["rerun-sdk"] [project.scripts] -graph_lattice = "graph_lattice:main" +graphs = "graphs:main" [build-system] requires = ["hatchling"] diff --git a/pixi.lock b/pixi.lock index cec6b0f84bfb..6dba1674cc76 100644 --- a/pixi.lock +++ b/pixi.lock @@ -2550,7 +2550,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -2954,7 +2954,7 @@ environments: - pypi: examples/python/dna - pypi: examples/python/drone_lidar - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar - pypi: examples/python/live_camera_edge_detection @@ -3339,7 +3339,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -3726,7 +3726,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -4112,7 +4112,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -4542,7 +4542,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -4898,7 +4898,7 @@ environments: - pypi: examples/python/dna - pypi: examples/python/drone_lidar - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar - pypi: examples/python/live_camera_edge_detection @@ -5236,7 +5236,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -5576,7 +5576,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -5916,7 +5916,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -9159,7 +9159,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -9657,7 +9657,7 @@ environments: - pypi: examples/python/dna - pypi: examples/python/drone_lidar - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar - pypi: examples/python/live_camera_edge_detection @@ -10135,7 +10135,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -10615,7 +10615,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -11074,7 +11074,7 @@ environments: - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - pypi: examples/python/graph_binary_tree - - pypi: examples/python/graph_lattice + - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -18052,13 +18052,6 @@ packages: requires_dist: - rerun-sdk editable: true -- pypi: examples/python/graph_lattice - name: graph-lattice - version: 0.1.0 - sha256: f92a889e55062d414fbf9847d0b2b216b8e4bcaf8ee2965476de877102ee52f8 - requires_dist: - - rerun-sdk - editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda sha256: 0595b009f20f8f60f13a6398e7cdcbd2acea5f986633adcf85f5a2283c992add md5: f87c7b7c2cb45f323ffbce941c78ab7c @@ -18113,6 +18106,13 @@ packages: purls: [] size: 95406 timestamp: 1711634622644 +- pypi: examples/python/graphs + name: graphs + version: 0.1.0 + sha256: 4e848c8bfec82cd0d79a4080a37ea03ee24c33d3c64019af981b76ba0bd8d10c + requires_dist: + - rerun-sdk + editable: true - pypi: https://files.pythonhosted.org/packages/eb/fc/570a1e503e19be24c5642ea8b93f23e3eef1dfa930e761cab72dedc2c2db/griffe-1.4.1-py3-none-any.whl name: griffe version: 1.4.1 diff --git a/pixi.toml b/pixi.toml index 4448ca0b884a..cdef11bbfb38 100644 --- a/pixi.toml +++ b/pixi.toml @@ -639,7 +639,7 @@ minimal_options = { path = "examples/python/minimal_options", editable = true } multiprocess_logging = { path = "examples/python/multiprocess_logging", editable = true } multithreading = { path = "examples/python/multithreading", editable = true } graph_binary_tree = { path = "examples/python/graph_binary_tree", editable = true } -graph_lattice = { path = "examples/python/graph_lattice", editable = true } +graphs = { path = "examples/python/graphs", editable = true } nuscenes_dataset = { path = "examples/python/nuscenes_dataset", editable = true } nv12 = { path = "examples/python/nv12", editable = true } objectron = { path = "examples/python/objectron", editable = true } diff --git a/tests/python/release_checklist/check_graph_time_layout.py b/tests/python/release_checklist/check_graph_time_layout.py deleted file mode 100644 index e10bde1053a5..000000000000 --- a/tests/python/release_checklist/check_graph_time_layout.py +++ /dev/null @@ -1,111 +0,0 @@ -from __future__ import annotations - -# TODO(grtlr): Promote to example -import os -import random -from argparse import Namespace -from uuid import uuid4 - -import rerun as rr -import rerun.blueprint as rrb - -# TODO(grtlr): Clean up the exports -from rerun.blueprint.archetypes.force_collision_radius import ForceCollisionRadius -from rerun.blueprint.archetypes.force_link import ForceLink -from rerun.blueprint.archetypes.force_many_body import ForceManyBody -from rerun.components.color import Color -from rerun.components.show_labels import ShowLabels - -README = """\ -# Time-varying graph view - -Please watch out for any twitching, jumping, or other wise unexpected changes to -the layout when navigating the timeline. - -Please check the following: -* Scrub the timeline to see how the graph layout changes over time. -""" - -color_scheme = [ - Color([228, 26, 28]), # Red - Color([55, 126, 184]), # Blue - Color([77, 175, 74]), # Green - Color([152, 78, 163]), # Purple - Color([255, 127, 0]), # Orange - Color([255, 255, 51]), # Yellow - Color([166, 86, 40]), # Brown - Color([247, 129, 191]), # Pink - Color([153, 153, 153]), # Gray -] - - -def log_readme() -> None: - rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), static=True) - - -def log_graphs() -> None: - nodes = ["root"] - radii = [42] - colors = [Color([81, 81, 81])] - edges = [] - - # We want reproducible results - random.seed(42) - - # Randomly add nodes and edges to the graph - for i in range(50): - existing = random.choice(nodes) - new_node = str(i) - nodes.append(new_node) - radii.append(random.randint(10, 50)) - colors.append(random.choice(color_scheme)) - edges.append((existing, new_node)) - - rr.set_time_sequence("frame", i) - rr.log( - "node_link", - rr.GraphNodes(nodes, labels=nodes, radii=radii, colors=colors), - rr.GraphEdges(edges, graph_type=rr.GraphType.Directed), - ) - rr.log( - "bubble_chart", - rr.GraphNodes(nodes, labels=nodes, radii=radii, colors=colors), - ) - - rr.send_blueprint( - rrb.Blueprint( - rrb.Grid( - rrb.GraphView( - origin="node_link", - name="Node-link diagram", - force_link=ForceLink(distance=60), - force_many_body=ForceManyBody(strength=-60), - ), - rrb.GraphView( - origin="bubble_chart", - name="Bubble chart", - force_link=ForceLink(enabled=False), - force_many_body=ForceManyBody(enabled=False), - force_collision_radius=ForceCollisionRadius(enabled=True), - defaults=[ShowLabels(False)], - ), - rrb.TextDocumentView(origin="readme", name="Instructions"), - ) - ) - ) - - -def run(args: Namespace) -> None: - rr.script_setup(args, f"{os.path.basename(__file__)}", recording_id=uuid4()) - - log_readme() - log_graphs() - - -if __name__ == "__main__": - import argparse - - parser = argparse.ArgumentParser(description="Interactive release checklist") - rr.script_add_args(parser) - args = parser.parse_args() - run(args) From 6559173da80d353e1f84cd268dea98d67542af52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 08:56:09 +0100 Subject: [PATCH 02/12] Fix bezier-edge again.. --- crates/viewer/re_view_graph/src/layout/provider.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/viewer/re_view_graph/src/layout/provider.rs b/crates/viewer/re_view_graph/src/layout/provider.rs index 6f84d1ff3f67..b49f3f6669a0 100644 --- a/crates/viewer/re_view_graph/src/layout/provider.rs +++ b/crates/viewer/re_view_graph/src/layout/provider.rs @@ -236,7 +236,7 @@ impl ForceLayoutProvider { let c1_base = source_pos + delta * 0.25; let c2_base = source_pos + delta * 0.75; - let base_n = Vec2::new(-c1_base.y, c1_base.x).normalized(); + let base_n = Vec2::new(-delta.y, delta.x).normalized(); let c1_left = c1_base + base_n * (fan_amount / 2.); let c2_left = c2_base + base_n * (fan_amount / 2.); From c267cccaf6a15cfabcb3df2c87c6816bb1e27209 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Thu, 12 Dec 2024 09:44:10 +0100 Subject: [PATCH 03/12] format --- crates/store/re_chunk/src/chunk.rs | 2 +- examples/python/graphs/graphs.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index b7ddcda62982..8184bb5178d7 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -74,7 +74,7 @@ impl ChunkComponents { } /// Returns all list arrays for the given component name. - /// + /// /// I.e semantically equivalent to `get("MyComponent:*.*")` #[inline] pub fn get_by_component_name<'a>( diff --git a/examples/python/graphs/graphs.py b/examples/python/graphs/graphs.py index 671a31a62fe8..7743b26d0d47 100644 --- a/examples/python/graphs/graphs.py +++ b/examples/python/graphs/graphs.py @@ -4,13 +4,12 @@ from __future__ import annotations import argparse -import random import itertools -import numpy as np +import random +import numpy as np import rerun as rr import rerun.blueprint as rrb - from rerun.blueprint.archetypes.force_collision_radius import ForceCollisionRadius from rerun.blueprint.archetypes.force_link import ForceLink from rerun.blueprint.archetypes.force_many_body import ForceManyBody @@ -18,7 +17,6 @@ from rerun.components.radius import Radius from rerun.components.show_labels import ShowLabels - color_scheme = [ Color([228, 26, 28]), # Red Color([55, 126, 184]), # Blue @@ -125,16 +123,19 @@ def log_markov_chain() -> None: Color([152, 78, 163]), # Purple ] - edges = [(state_names[i], state_names[j]) for i in range(len(state_names)) for j in range(len(state_names)) if transition_matrix[i][j] > 0] + edges = [ + (state_names[i], state_names[j]) + for i in range(len(state_names)) + for j in range(len(state_names)) + if transition_matrix[i][j] > 0 + ] # We start in state "sunny" state = "sunny" for i in range(50): current_state_index = state_names.index(state) - next_state_index = np.random.choice( - range(len(state_names)), p=transition_matrix[current_state_index] - ) + next_state_index = np.random.choice(range(len(state_names)), p=transition_matrix[current_state_index]) state = state_names[next_state_index] colors = [inactive_color] * len(state_names) colors[next_state_index] = active_colors[next_state_index] @@ -145,11 +146,10 @@ def log_markov_chain() -> None: rr.log( "markov_chain", rr.GraphNodes(state_names, labels=state_names, colors=colors, positions=positions), - rr.GraphEdges(edges, graph_type="directed") + rr.GraphEdges(edges, graph_type="directed"), ) - def log_blueprint() -> None: rr.send_blueprint( rrb.Blueprint( @@ -182,7 +182,7 @@ def log_blueprint() -> None: # We don't need any forces for this graph, because the nodes have fixed positions. ), rrb.TextDocumentView(origin="description", name="Description"), - ) + ), ) ) ) From 979844f4a64727cc232c0e9ee7ac5cf87e0a546f Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Thu, 12 Dec 2024 09:49:56 +0100 Subject: [PATCH 04/12] ignore graph_lattice --- examples/manifest.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/manifest.toml b/examples/manifest.toml index 5be17e03604d..b229b765acd5 100644 --- a/examples/manifest.toml +++ b/examples/manifest.toml @@ -169,6 +169,7 @@ examples = [ "extend_viewer_ui", "external_data_loader", "graph_binary_tree", + "graph_lattice", "incremental_logging", "minimal_serve", "shared_recording", From d0b68e938214105bbce6094768194734ac6fb9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:01:37 +0100 Subject: [PATCH 05/12] Remove unneeded --- crates/viewer/re_view_graph/src/view.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/viewer/re_view_graph/src/view.rs b/crates/viewer/re_view_graph/src/view.rs index eaf2068663ee..8948a343c423 100644 --- a/crates/viewer/re_view_graph/src/view.rs +++ b/crates/viewer/re_view_graph/src/view.rs @@ -180,7 +180,6 @@ Display a graph of nodes and edges. // Perform all layout-related tasks. let request = LayoutRequest::from_graphs(graphs.iter()); - let layout_was_empty = state.layout_state.is_none(); let layout = state.layout_state.get(request, params); // Prepare the view and the transformations. @@ -216,7 +215,7 @@ Display a graph of nodes and edges. // Update blueprint if changed let updated_rect_in_scene = blueprint::components::VisualBounds2D::from(ui_from_world.inverse() * rect_in_ui); - if resp.double_clicked() || layout_was_empty { + if resp.double_clicked() { bounds_property.reset_blueprint_component::(ctx); state.ui_from_world = None; } else if rect_in_scene != updated_rect_in_scene { From b74349d0d6cc7d7860bb171081e58d589dbf25f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:10:20 +0100 Subject: [PATCH 06/12] Add implicit node to Markov-Chain --- examples/python/graphs/graphs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/python/graphs/graphs.py b/examples/python/graphs/graphs.py index 7743b26d0d47..942a8ad3b01c 100644 --- a/examples/python/graphs/graphs.py +++ b/examples/python/graphs/graphs.py @@ -129,6 +129,7 @@ def log_markov_chain() -> None: for j in range(len(state_names)) if transition_matrix[i][j] > 0 ] + edges.append(("start", "sunny")) # We start in state "sunny" state = "sunny" @@ -140,8 +141,6 @@ def log_markov_chain() -> None: colors = [inactive_color] * len(state_names) colors[next_state_index] = active_colors[next_state_index] - print(colors) - rr.set_time_sequence("frame", i) rr.log( "markov_chain", From 6bfbaed7b00b1f024a11ce0819a95f54b9275d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:12:50 +0100 Subject: [PATCH 07/12] Remove `graph_binary_tree` example --- Cargo.lock | 9 - examples/python/graph_binary_tree/README.md | 28 ---- .../graph_binary_tree/graph_binary_tree.py | 108 ------------ .../python/graph_binary_tree/pyproject.toml | 12 -- examples/rust/graph_binary_tree/Cargo.toml | 13 -- examples/rust/graph_binary_tree/README.md | 3 - examples/rust/graph_binary_tree/src/main.rs | 155 ------------------ pixi.lock | 22 --- pixi.toml | 1 - 9 files changed, 351 deletions(-) delete mode 100644 examples/python/graph_binary_tree/README.md delete mode 100644 examples/python/graph_binary_tree/graph_binary_tree.py delete mode 100644 examples/python/graph_binary_tree/pyproject.toml delete mode 100644 examples/rust/graph_binary_tree/Cargo.toml delete mode 100644 examples/rust/graph_binary_tree/README.md delete mode 100644 examples/rust/graph_binary_tree/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 4a5eee7bfb59..ec0e3d7deb44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2915,15 +2915,6 @@ dependencies = [ "bitflags 2.6.0", ] -[[package]] -name = "graph_binary_tree" -version = "0.21.0-alpha.1+dev" -dependencies = [ - "anyhow", - "clap", - "rerun", -] - [[package]] name = "graph_lattice" version = "0.21.0-alpha.1+dev" diff --git a/examples/python/graph_binary_tree/README.md b/examples/python/graph_binary_tree/README.md deleted file mode 100644 index 1165823aa39f..000000000000 --- a/examples/python/graph_binary_tree/README.md +++ /dev/null @@ -1,28 +0,0 @@ - - -This example shows a binary tree that uses `GraphNodes` and `GraphEdges` together with fixed node positions. - - - - - - - - - -## Used Rerun types -[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link), -[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link) - -## Run the code - -```bash -pip install -e examples/python/graph_binary_tree -python -m graph_binary_tree -``` diff --git a/examples/python/graph_binary_tree/graph_binary_tree.py b/examples/python/graph_binary_tree/graph_binary_tree.py deleted file mode 100644 index 96f9a2c869a1..000000000000 --- a/examples/python/graph_binary_tree/graph_binary_tree.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python3 -"""Examples of logging graph data to Rerun.""" - -from __future__ import annotations - -import argparse - -import rerun as rr - -DESCRIPTION = """ -# Binary tree -This is a minimal example that logs a time-varying binary tree to Rerun. - -The full source code for this example is available -[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graph_binary_tree?speculative-link). -""".strip() - -s = 3 # scaling factor for the positions - -# Potentially unbalanced and not sorted binary tree. :nerd_face:. -# :warning: The nodes have to be unique, which is why we use `5_0`… - -NodeId = str - - -class NodeInfo: - def __init__(self, label: str, pos: tuple[float, float]) -> None: - self.label = label - self.pos = pos - - -all_nodes: dict[NodeId, NodeInfo] = { - "1": NodeInfo(label="1", pos=(0 * s, 0 * s)), - "7": NodeInfo(label="7", pos=(-20 * s, 30 * s)), - "2": NodeInfo(label="2", pos=(-30 * s, 60 * s)), - "6": NodeInfo(label="6", pos=(-10 * s, 60 * s)), - "5_0": NodeInfo(label="5", pos=(-20 * s, 90 * s)), - "11": NodeInfo(label="11", pos=(0 * s, 90 * s)), - "9_0": NodeInfo(label="9", pos=(20 * s, 30 * s)), - "9_1": NodeInfo(label="9", pos=(30 * s, 60 * s)), - "5_1": NodeInfo(label="5", pos=(20 * s, 90 * s)), -} - - -class Level: - def __init__(self, nodes: list[NodeId], edges: list[tuple[NodeId, NodeId]]): - self.nodes = nodes - self.edges = edges - - -levels: list[Level] = [ - Level(nodes=["1"], edges=[]), - Level(nodes=["1", "7", "9_0"], edges=[("1", "7"), ("1", "9_0")]), - Level( - nodes=["1", "7", "9_0", "2", "6", "9_1"], - edges=[("1", "7"), ("1", "9_0"), ("7", "2"), ("7", "6"), ("9_0", "9_1")], - ), - Level( - nodes=["1", "7", "9_0", "2", "6", "9_1", "5_0", "11", "5_1"], - edges=[ - ("1", "7"), - ("1", "9_0"), - ("7", "2"), - ("7", "6"), - ("9_0", "9_1"), - ("6", "5_0"), - ("6", "11"), - ("9_1", "5_1"), - ], - ), -] - - -def log_data() -> None: - rr.log("description", rr.TextDocument(DESCRIPTION, media_type=rr.MediaType.MARKDOWN), static=True) - - t = 0 - for level in levels: - if len(level.nodes) > 0: - t = t + 1 - rr.set_time_seconds("stable_time", t) - rr.log( - "binary_tree", - rr.GraphNodes( - level.nodes, - labels=list(map(lambda n: all_nodes[n].label, level.nodes)), - positions=list(map(lambda n: all_nodes[n].pos, level.nodes)), - ), - ) - - if len(level.edges) > 0: - t = t + 1 - rr.set_time_seconds("stable_time", t) - rr.log("binary_tree", rr.GraphEdges(level.edges)) - - -def main() -> None: - parser = argparse.ArgumentParser(description="Logs a binary tree with associated positions using the Rerun SDK.") - rr.script_add_args(parser) - args = parser.parse_args() - - rr.script_setup(args, "rerun_example_graph_binary_tree") - log_data() - rr.script_teardown(args) - - -if __name__ == "__main__": - main() diff --git a/examples/python/graph_binary_tree/pyproject.toml b/examples/python/graph_binary_tree/pyproject.toml deleted file mode 100644 index a10385ee722a..000000000000 --- a/examples/python/graph_binary_tree/pyproject.toml +++ /dev/null @@ -1,12 +0,0 @@ -[project] -name = "graph_binary_tree" -version = "0.1.0" -readme = "README.md" -dependencies = ["rerun-sdk"] - -[project.scripts] -graph_binary_tree = "graph_binary_tree:main" - -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" diff --git a/examples/rust/graph_binary_tree/Cargo.toml b/examples/rust/graph_binary_tree/Cargo.toml deleted file mode 100644 index 34af848c8320..000000000000 --- a/examples/rust/graph_binary_tree/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "graph_binary_tree" -version = "0.21.0-alpha.1+dev" -edition = "2021" -rust-version = "1.80" -license = "MIT OR Apache-2.0" -publish = false - -[dependencies] -rerun = { path = "../../../crates/top/rerun", features = ["clap"] } - -anyhow = "1.0" -clap = { version = "4.0", features = ["derive"] } diff --git a/examples/rust/graph_binary_tree/README.md b/examples/rust/graph_binary_tree/README.md deleted file mode 100644 index 110ff4de97b1..000000000000 --- a/examples/rust/graph_binary_tree/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# graph_binary_tree - -Demonstrates visualization of a graph that varies over time. diff --git a/examples/rust/graph_binary_tree/src/main.rs b/examples/rust/graph_binary_tree/src/main.rs deleted file mode 100644 index 1f820fa28f0a..000000000000 --- a/examples/rust/graph_binary_tree/src/main.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! Shows how to draw a graph that varies over time. -//! Please not that this example makes use of fixed positions. -//! -//! Usage: -//! ``` -//! cargo run -p graph_binary_tree -- --connect -//! ``` - -use rerun::{external::re_log, GraphEdges, GraphNodes}; -use std::collections::HashMap; - -#[derive(Debug, clap::Parser)] -#[clap(author, version, about)] -pub struct Args { - #[command(flatten)] - rerun: rerun::clap::RerunArgs, -} - -fn main() -> anyhow::Result<()> { - re_log::setup_logging(); - - use clap::Parser as _; - let args = Args::parse(); - - let (rec, _serve_guard) = args.rerun.init("rerun_example_graph_binary_tree")?; - - let s = 3.0; // scaling factor for the positions - - // Potentially unbalanced and not sorted binary tree. :nerd_face:. - // :warning: The nodes have to be unique, which is why we use `5_0`… - - // (label, position) - type NodeInfo = (&'static str, (f32, f32)); - - struct Level<'a> { - nodes: &'a [&'a str], - edges: &'a [(&'a str, &'a str)], - } - - let nodes_unsorted: HashMap<&str, NodeInfo> = [ - ("1", ("1", (0.0 * s, 0.0 * s))), - ("7", ("7", (-20.0 * s, 30.0 * s))), - ("2", ("2", (-30.0 * s, 60.0 * s))), - ("6", ("6", (-10.0 * s, 60.0 * s))), - ("5_0", ("5", (-20.0 * s, 90.0 * s))), - ("11", ("11", (0.0 * s, 90.0 * s))), - ("9_0", ("9", (20.0 * s, 30.0 * s))), - ("9_1", ("9", (30.0 * s, 60.0 * s))), - ("5_1", ("5", (20.0 * s, 90.0 * s))), - ] - .into_iter() - .collect(); - - let levels_unsorted: Vec = vec![ - Level { - nodes: &["1"], - edges: &[], - }, - Level { - nodes: &["1", "7", "9_0"], - edges: &[("1", "7"), ("1", "9_0")], - }, - Level { - nodes: &["1", "7", "9_0", "2", "6", "9_1"], - edges: &[ - ("1", "7"), - ("1", "9_0"), - ("7", "2"), - ("7", "6"), - ("9_0", "9_1"), - ], - }, - Level { - nodes: &["1", "7", "9_0", "2", "6", "9_1", "5_0", "11", "5_1"], - edges: &[ - ("1", "7"), - ("1", "9_0"), - ("7", "2"), - ("7", "6"), - ("9_0", "9_1"), - ("6", "5_0"), - ("6", "11"), - ("9_1", "5_1"), - ], - }, - ]; - - let nodes_sorted: HashMap<&str, NodeInfo> = [ - ("6", ("6", (0.0 * s, 0.0 * s))), - ("5_0", ("5", (-20.0 * s, 30.0 * s))), - ("9_0", ("9", (20.0 * s, 30.0 * s))), - ] - .into_iter() - .collect(); - - let levels_sorted: Vec = vec![ - Level { - nodes: &["6"], - edges: &[], - }, - Level { - nodes: &["6", "5_0", "9_0"], - edges: &[("6", "5_0"), ("6", "9_0"), ("1", "6"), ("1", "42")], - }, - ]; - - let mut t = 0; - for level in levels_unsorted { - if !level.nodes.is_empty() { - t += 1; - rec.set_time_seconds("stable_time", t as f64); - let _ = rec.log( - "unsorted", - &GraphNodes::new(level.nodes.iter().copied()) - .with_labels(level.nodes.iter().map(|n| nodes_unsorted[n].0)) - .with_positions(level.nodes.iter().map(|n| nodes_unsorted[n].1)), - ); - } - - if !level.edges.is_empty() { - t += 1; - rec.set_time_seconds("stable_time", t as f64); - let _ = rec.log("unsorted", &GraphEdges::new(level.edges)); - } - } - - let entity_offset_x = 200.0; - - for level in levels_sorted { - if !level.nodes.is_empty() { - t += 1; - rec.set_time_seconds("stable_time", t as f64); - let _ = rec.log( - "sorted", - &GraphNodes::new(level.nodes.iter().copied()) - .with_labels(level.nodes.iter().map(|n| nodes_sorted[n].0)) - .with_positions(level.nodes.iter().map(|n| { - let (x, y) = nodes_sorted[n].1; - [x + entity_offset_x, y] - })), - ); - } - - if !level.edges.is_empty() { - t += 1; - rec.set_time_seconds("stable_time", t as f64); - let _ = rec.log( - "sorted", - &GraphEdges::new(level.edges).with_directed_edges(), - ); - } - } - - Ok(()) -} diff --git a/pixi.lock b/pixi.lock index 6dba1674cc76..fa83a1acc7e6 100644 --- a/pixi.lock +++ b/pixi.lock @@ -2549,7 +2549,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -2953,7 +2952,6 @@ environments: - pypi: examples/python/dicom_mri - pypi: examples/python/dna - pypi: examples/python/drone_lidar - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -3338,7 +3336,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -3725,7 +3722,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -4111,7 +4107,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -4541,7 +4536,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -4897,7 +4891,6 @@ environments: - pypi: examples/python/dicom_mri - pypi: examples/python/dna - pypi: examples/python/drone_lidar - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -5235,7 +5228,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -5575,7 +5567,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -5915,7 +5906,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -9158,7 +9148,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -9656,7 +9645,6 @@ environments: - pypi: examples/python/dicom_mri - pypi: examples/python/dna - pypi: examples/python/drone_lidar - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -10134,7 +10122,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -10614,7 +10601,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -11073,7 +11059,6 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection - - pypi: examples/python/graph_binary_tree - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -18045,13 +18030,6 @@ packages: - protobuf!=3.20.0,!=3.20.1,>=3.20.2,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0.dev0 - grpcio>=1.44.0,<2.0.0.dev0 ; extra == 'grpc' requires_python: '>=3.7' -- pypi: examples/python/graph_binary_tree - name: graph-binary-tree - version: 0.1.0 - sha256: 8ceb8c2d1102f2f2476eb5fb9c79e717e520f92220709449f48138a3c84c6609 - requires_dist: - - rerun-sdk - editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda sha256: 0595b009f20f8f60f13a6398e7cdcbd2acea5f986633adcf85f5a2283c992add md5: f87c7b7c2cb45f323ffbce941c78ab7c diff --git a/pixi.toml b/pixi.toml index cdef11bbfb38..053002cd8c37 100644 --- a/pixi.toml +++ b/pixi.toml @@ -638,7 +638,6 @@ minimal = { path = "examples/python/minimal", editable = true } minimal_options = { path = "examples/python/minimal_options", editable = true } multiprocess_logging = { path = "examples/python/multiprocess_logging", editable = true } multithreading = { path = "examples/python/multithreading", editable = true } -graph_binary_tree = { path = "examples/python/graph_binary_tree", editable = true } graphs = { path = "examples/python/graphs", editable = true } nuscenes_dataset = { path = "examples/python/nuscenes_dataset", editable = true } nv12 = { path = "examples/python/nv12", editable = true } From 97337ffedd9fd1a4f652e26ef336082df1b73c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:15:59 +0100 Subject: [PATCH 08/12] Update examples/python/graphs/graphs.py Co-authored-by: Clement Rey --- examples/python/graphs/graphs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/graphs/graphs.py b/examples/python/graphs/graphs.py index 942a8ad3b01c..4c3e0cd26f75 100644 --- a/examples/python/graphs/graphs.py +++ b/examples/python/graphs/graphs.py @@ -77,7 +77,7 @@ def log_lattice(num_nodes) -> None: target = y * num_nodes + x edges.append((str(source), str(target))) - rr.log("/lattice", rr.GraphEdges(edges, graph_type="directed"), static=True) + rr.log("lattice", rr.GraphEdges(edges, graph_type="directed"), static=True) def log_trees() -> None: From 79b2df1dc2e3c600bb984d7a6f0bf342790d6bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:31:23 +0100 Subject: [PATCH 09/12] Bring back `graph_lattice` --- examples/python/graph_lattice/README.md | 29 ++++++++ .../python/graph_lattice/graph_lattice.py | 72 +++++++++++++++++++ examples/python/graph_lattice/pyproject.toml | 12 ++++ pixi.lock | 22 ++++++ pixi.toml | 1 + 5 files changed, 136 insertions(+) create mode 100644 examples/python/graph_lattice/README.md create mode 100644 examples/python/graph_lattice/graph_lattice.py create mode 100644 examples/python/graph_lattice/pyproject.toml diff --git a/examples/python/graph_lattice/README.md b/examples/python/graph_lattice/README.md new file mode 100644 index 000000000000..8ffe2530634f --- /dev/null +++ b/examples/python/graph_lattice/README.md @@ -0,0 +1,29 @@ + + +This example shows different attributes that you can associate with nodes in a graph. +Since no explicit positions are passed for the nodes, Rerun will layout the graph automatically. + + + + + + + + + +## Used Rerun types +[`GraphNodes`](https://www.rerun.io/docs/reference/types/archetypes/graph_nodes?speculative-link), +[`GraphEdges`](https://www.rerun.io/docs/reference/types/archetypes/graph_edges?speculative-link) + +## Run the code + + ```bash + pip install -e examples/python/graph_lattice + python -m graph_lattice + ``` diff --git a/examples/python/graph_lattice/graph_lattice.py b/examples/python/graph_lattice/graph_lattice.py new file mode 100644 index 000000000000..21eb327df1ca --- /dev/null +++ b/examples/python/graph_lattice/graph_lattice.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Examples of logging graph data to Rerun and performing a force-based layout.""" + +from __future__ import annotations + +import argparse +import itertools + +import rerun as rr + +NUM_NODES = 10 + +DESCRIPTION = """ +# Graph Lattice +This is a minimal example that logs a graph (node-link diagram) that represents a lattice. + +In this example, the node positions—and therefore the graph layout—are computed by Rerun internally. + +The full source code for this example is available +[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/graph_lattice?speculative-link). +""".strip() + + +def log_data() -> None: + rr.log("description", rr.TextDocument(DESCRIPTION, media_type=rr.MediaType.MARKDOWN), static=True) + + coordinates = itertools.product(range(NUM_NODES), range(NUM_NODES)) + + nodes, colors = zip(*[ + ( + str(i), + rr.components.Color([round((x / (NUM_NODES - 1)) * 255), round((y / (NUM_NODES - 1)) * 255), 0]), + ) + for i, (x, y) in enumerate(coordinates) + ]) + + rr.log( + "/lattice", + rr.GraphNodes( + nodes, + colors=colors, + labels=[f"({x}, {y})" for x, y in itertools.product(range(NUM_NODES), range(NUM_NODES))], + ), + static=True, + ) + + edges = [] + for x, y in itertools.product(range(NUM_NODES), range(NUM_NODES)): + if y > 0: + source = (y - 1) * NUM_NODES + x + target = y * NUM_NODES + x + edges.append((str(source), str(target))) + if x > 0: + source = y * NUM_NODES + (x - 1) + target = y * NUM_NODES + x + edges.append((str(source), str(target))) + + rr.log("/lattice", rr.GraphEdges(edges, graph_type="directed"), static=True) + + +def main() -> None: + parser = argparse.ArgumentParser(description="Logs a graph lattice using the Rerun SDK.") + rr.script_add_args(parser) + args = parser.parse_args() + + rr.script_setup(args, "rerun_example_graph_lattice") + log_data() + rr.script_teardown(args) + + +if __name__ == "__main__": + main() diff --git a/examples/python/graph_lattice/pyproject.toml b/examples/python/graph_lattice/pyproject.toml new file mode 100644 index 000000000000..2244974c6700 --- /dev/null +++ b/examples/python/graph_lattice/pyproject.toml @@ -0,0 +1,12 @@ +[project] + name = "graph_lattice" + version = "0.1.0" + readme = "README.md" + dependencies = ["rerun-sdk"] + + [project.scripts] + graph_lattice = "graph_lattice:main" + + [build-system] + requires = ["hatchling"] + build-backend = "hatchling.build" diff --git a/pixi.lock b/pixi.lock index fa83a1acc7e6..0f9ebef4c384 100644 --- a/pixi.lock +++ b/pixi.lock @@ -2549,6 +2549,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -2952,6 +2953,7 @@ environments: - pypi: examples/python/dicom_mri - pypi: examples/python/dna - pypi: examples/python/drone_lidar + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -3336,6 +3338,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -3722,6 +3725,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -4107,6 +4111,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -4536,6 +4541,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -4891,6 +4897,7 @@ environments: - pypi: examples/python/dicom_mri - pypi: examples/python/dna - pypi: examples/python/drone_lidar + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -5228,6 +5235,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -5567,6 +5575,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -5906,6 +5915,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -9148,6 +9158,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -9645,6 +9656,7 @@ environments: - pypi: examples/python/dicom_mri - pypi: examples/python/dna - pypi: examples/python/drone_lidar + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/incremental_logging - pypi: examples/python/lidar @@ -10122,6 +10134,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -10601,6 +10614,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -11059,6 +11073,7 @@ environments: - pypi: examples/python/drone_lidar - pypi: examples/python/face_tracking - pypi: examples/python/gesture_detection + - pypi: examples/python/graph_lattice - pypi: examples/python/graphs - pypi: examples/python/human_pose_tracking - pypi: examples/python/incremental_logging @@ -18030,6 +18045,13 @@ packages: - protobuf!=3.20.0,!=3.20.1,>=3.20.2,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0.dev0 - grpcio>=1.44.0,<2.0.0.dev0 ; extra == 'grpc' requires_python: '>=3.7' +- pypi: examples/python/graph_lattice + name: graph-lattice + version: 0.1.0 + sha256: 2e1f113e9481bd553a677fca031e2800a4d71acb6326a1990dcbaea66ddeae51 + requires_dist: + - rerun-sdk + editable: true - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda sha256: 0595b009f20f8f60f13a6398e7cdcbd2acea5f986633adcf85f5a2283c992add md5: f87c7b7c2cb45f323ffbce941c78ab7c diff --git a/pixi.toml b/pixi.toml index 053002cd8c37..72217e1239c9 100644 --- a/pixi.toml +++ b/pixi.toml @@ -638,6 +638,7 @@ minimal = { path = "examples/python/minimal", editable = true } minimal_options = { path = "examples/python/minimal_options", editable = true } multiprocess_logging = { path = "examples/python/multiprocess_logging", editable = true } multithreading = { path = "examples/python/multithreading", editable = true } +graph_lattice = { path = "examples/python/graph_lattice", editable = true } graphs = { path = "examples/python/graphs", editable = true } nuscenes_dataset = { path = "examples/python/nuscenes_dataset", editable = true } nv12 = { path = "examples/python/nv12", editable = true } From 70a29b0e159479def8ee13e8cbe2c13cd18b8904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:35:12 +0100 Subject: [PATCH 10/12] Fmt --- examples/python/graph_lattice/pyproject.toml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/python/graph_lattice/pyproject.toml b/examples/python/graph_lattice/pyproject.toml index 2244974c6700..128b7879d28e 100644 --- a/examples/python/graph_lattice/pyproject.toml +++ b/examples/python/graph_lattice/pyproject.toml @@ -1,12 +1,12 @@ [project] - name = "graph_lattice" - version = "0.1.0" - readme = "README.md" - dependencies = ["rerun-sdk"] +name = "graph_lattice" +version = "0.1.0" +readme = "README.md" +dependencies = ["rerun-sdk"] - [project.scripts] - graph_lattice = "graph_lattice:main" +[project.scripts] +graph_lattice = "graph_lattice:main" - [build-system] - requires = ["hatchling"] - build-backend = "hatchling.build" +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" From 7c6e7b726552fb70b36085c3cefdff9432971a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 10:38:18 +0100 Subject: [PATCH 11/12] Update `pixi.lock` --- pixi.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pixi.lock b/pixi.lock index 0f9ebef4c384..704ab17f98a4 100644 --- a/pixi.lock +++ b/pixi.lock @@ -18048,7 +18048,7 @@ packages: - pypi: examples/python/graph_lattice name: graph-lattice version: 0.1.0 - sha256: 2e1f113e9481bd553a677fca031e2800a4d71acb6326a1990dcbaea66ddeae51 + sha256: f92a889e55062d414fbf9847d0b2b216b8e4bcaf8ee2965476de877102ee52f8 requires_dist: - rerun-sdk editable: true From fa5809c9572a6260c00a181a17decec7051bc6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Thu, 12 Dec 2024 12:15:33 +0100 Subject: [PATCH 12/12] Missing type --- examples/python/graphs/graphs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/graphs/graphs.py b/examples/python/graphs/graphs.py index 4c3e0cd26f75..3bf490c625d9 100644 --- a/examples/python/graphs/graphs.py +++ b/examples/python/graphs/graphs.py @@ -45,7 +45,7 @@ random.seed(42) -def log_lattice(num_nodes) -> None: +def log_lattice(num_nodes: int) -> None: coordinates = itertools.product(range(num_nodes), range(num_nodes)) nodes, colors = zip(*[