rerun-blueprint について
rerun-blueprintは、Rerunの記録やテーブルの表示方法を設定するスキルです。データを確認してビューとレイアウトを設計し、スクリーンショットを見ながらブループリントを調整します。
主な機能
- 01記録のビューとレイアウト設定
- 02テーブル列、フィルター、カードの設定
- 03エンティティとアーキタイプに応じたビュー選択
- 04ビューの配置と表示範囲の指定
- 05スクリーンショットによる調整
活用シーン
- 01記録データの複数ビューを設計
- 02データセットの列や行フィルターを調整
- 03空の空間ビューやレイアウトの問題を調査
MCP 対応
viewer MCPでrerun_get_blueprintを使ってブループリントを読み、rerun_set_blueprintで書き込みます。テーブルスキーマの確認とテーブル設定の更新にも対応します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rerun-io/ rerun --skill rerun-blueprintインストール後、Claude Code で/rerun-blueprintを入力して読み込まれたか確認します。
詳細
Rerun ブループリント
**ビューアーの見た目を変えるには、ブループリントを変更します。**これは、記録のレイアウト、ビューとそのプロパティ、テーブルの列、行フィルター、カードに当てはまります。ビューアーのメニューをクリックして変更しないでください。ビューアー MCP では、低レベルのクリックツールではなく、rerun_get_blueprint と
rerun_set_blueprint を使ってブループリントを読み書きします。
ブループリントは記録の表示方法を決め、記録は何が存在するかを決めます。
データを読み、最初のレイアウトを設計し、ひと目で内容がわかるまでスクリーンショットを見ながら調整します。コンストラクターは確認できます(dir(rrb)、
help(rrb.Spatial3DView))。このスキルでは、推測できない部分を説明します。import rerun.blueprint as rrb としてインポートします。
テーブル
データセットのセグメントテーブルとカタログテーブルには、それぞれ独自のテーブルブループリントがあり、記録のブループリントとは別です。表示する列、その順序と名前、行フィルター、行をテーブルとカードのどちらで表示するかを設定します。テーブルの見た目を整えるよう依頼された場合は、このブループリントを書き換えます。
次の例では、2 つの列を非表示にし、別の 3 つの列を先頭に表示します。列の一覧にある列が先頭に並び、それ以外の列はデフォルトの順序と表示設定を維持します。
blueprint = rrb.TableBlueprint(
table_layout=rrb.table.TableLayout(
columns=[
rrb.table.Column("recording link"),
rrb.table.Column("property:episode:current_task", name="Task"),
rrb.table.Column("property:episode:success"),
rrb.table.Column("property:episode:ext1_cam_serial", visible=False),
rrb.table.Column("property:episode:ext2_cam_serial", visible=False),
],
),
)
blueprint.save("my_app", path)
dataset.register_blueprint(path.as_uri(), segment_table=True)
Column には、ヘッダー名ではなく、property:episode:uuid のようにテーブル上の列名を指定します。登録すると、そのテーブルを開くすべてのユーザーに対するデフォルトになります。また、サーバーが path を読み取れる必要があります。
行フィルターは SQL 式で、文字列ごとに 1 つ指定し、すべての式が行に対して真である必要があります。例:rrb.TableBlueprint(filters=["\"task\" ILIKE '%pick%'", '"duration" > 10'])。列名には二重引用符、文字列には一重引用符を使います。リスト列には any_match("column", x -> …) を使います。
ビューアー MCP では、画面上のテーブルを直接変更できます。
rerun_get_table_schema で列名を確認し、{"table": {}} を指定した rerun_get_blueprint でテーブルブループリントを読み取り、{"table": {}} を指定した rerun_set_blueprint で置き換えます。フィルターが無効な場合、rerun_set_blueprint はエラーを返します。列のエントリーは /table/layouts/table/columns/<column name> にあり、名前に含まれる各 : とスペースは \: と \ にエスケープします。JSON ではそれぞれ \\: と \\ と記述します。JSON の具体例は MCP docs をご覧ください。カードやセグメントプレビューも含めた Python API 全体については、テーブルレイアウトとセグメントプレビューを設定する をご覧ください。
1. データを読む
まず、すべての (entity_path, archetype) の組み合わせを列挙します。archetype はビューを選び、entity path はその対象範囲を指定します。データセットの場合は(rerun-catalog-queries を参照):
for c in dataset.schema().component_columns():
print(c.entity_path, c.archetype, c.component_name)
ローカルの記録の場合は、RrdReader でストリーミングし、各チャンクから entity_path と archetype を読み取ります(rerun-chunk-processing を参照)。
データセットのスキーマだけでは、ビューに表示できるすべてのエンティティはわかりません。アセットとは URDF ロボットメッシュのような静的データで、ビューアーはこれをすべてのセグメントに適用しますが、セグメントエンティティには表示されません。rerun_get_dataset_schema が entities と並べて asset_ids を表示する場合は、rerun_get_dataset_assets_schema を呼び出して各アセット内のエンティティを取得し、2D ビューと 3D ビューのどちらを選ぶか、またはプレビューを選ぶ前に読み取ります。たとえば、asset_ids: ["urdf-model-left", "urdf-model-right"] は、ロボットモデルを Spatial3DView に表示できることを意味します。
2. アーキタイプをビューに対応付ける
| アーキタイプの種類 | ビュー |
|---|---|
Points2D, Image, EncodedImage, Boxes2D, LineStrips2D, Pinhole projections | Spatial2DView |
Points3D, Mesh3D, Boxes3D, LineStrips3D, Transform3D, Asset3D | Spatial3DView |
Scalars, SeriesLines, SeriesPoints | TimeSeriesView |
TextLog / TextDocument / BarChart | TextLogView / TextDocumentView / BarChartView |
Tensor, DepthImage(ヒートマップ) | TensorView |
GeoPoints, GeoLineStrings | MapView |
GraphNodes, GraphEdges | GraphView |
| 表形式データ/カタログデータ | DataframeView |
Asset3D や URDF メッシュなどのアセットエンティティは、Spatial3DView に配置します。
3. エンティティをビューにまとめる
このステップでは、どのエンティティを同じビューに配置するかだけを決めます。サイズや配置は、スクリーンショットを確認しながら調整するもので、事前にルールとして決める必要はありません。
- 共通のパスプレフィックスごとにまとめます。 共通のプレフィックス配下にあるエンティティは、通常、1つのビューにまとめます。エンティティごとにペインを作らないでください。生のメッセージエンティティが何十個もある場合は、それぞれ別のペインにするのではなく、1つの
DataframeViewにまとめるか、表示対象から外します。 - 空間ビューごとに空間フレームは1つにします。
Transform3Dツリー全体は、共通の祖先をSpatial3DViewの起点として、1つのビューに配置します。Pinholeカメラは、画像が投影を継承するよう、カメラを起点とする独自のSpatial2DViewに配置します。 - スカラーをまとめます。 1つのプレフィックス配下に多数の
Scalarsがある場合、それぞれ個別に配置するのではなく、プレフィックス全体を対象にした1つのTimeSeriesViewにまとめます。値の範囲が合わない場合にのみ分割します。 column_shares/row_sharesは、コンテナ内の子要素に対する相対的な重みです。 デフォルトでは均等です。スクリーンショットを見て調整します。
4. 構成する
コンテナ(Grid、Horizontal、Vertical、Tabs)にビューを配置します。フラットなビュー群には Grid をデフォルトとして使います。意図的に分割する場合はほかのコンテナを使い、同じ場所を取り合う選択肢(左/右/深度カメラなど)には Tabs を使います。必ず明示的に origin と name を設定してください。 origin のデフォルトは / で、ツリー全体が1つのビューに詰め込まれてしまいます(読みにくい塊になる主な原因です)。
blueprint = rrb.Blueprint(
rrb.Horizontal(
rrb.Spatial3DView(origin="/world", name="Scene"),
rrb.Vertical(
rrb.Spatial2DView(origin="/world/camera", name="Camera"),
rrb.TimeSeriesView(origin="/sensors", name="Sensors"),
),
column_shares=[3, 2],
),
rrb.TextLogView(origin="/logs", name="Logs"),
collapse_panels=True,
)
contents のデフォルトは "$origin/**" です。包含/除外ルールでビューの対象を絞り込みます。例:contents=["+ $origin/**", "- $origin/internal/**"]。プレフィックスのない行は包含ルールです。ワイルドカードは /** のみで(サブツリーに一致します)。最も具体的なルールが優先され、同じ具体性の場合は後のルールが優先され、一致するパスがない場合は除外されます。
座標フレーム。 空間ビューでレンダリングされるのは、対象フレームに対する位置を特定できるエンティティのみです。エンティティに記録された Transform3D/Pinhole はツリーに沿って合成されるため、origin を指定するだけで十分です。一方、名前付きフレーム(ROS/MCAP で一般的な CoordinateFrame(frame=...))は独立したフレームグラフに存在します。そのため、spatial_information=rrb.SpatialInformation(target_frame="<frame>") を使って、データが存在するフレームをビューの対象に指定します。空の3Dビューに「No transform path from <frame>…」というエラーが表示される場合は、これが原因です。origin="/" はルート tf#/ を対象にしますが、tf ツリーが実体化されていない場合、そこには何も接続されません。CoordinateFrame:frame の値を調べ、主要な3Dコンテンツが存在するフレームを対象に指定し、接続されていないフレーム内のエンティティを除外します。
5. スクリーンショットから反復する
ビューアーを起動して記録を一度読み込んだら、同じビューアーにブループリントを再送します。送信とスクリーンショットの組み合わせが、手軽な反復作業の1回分です。レンダリングして確認し、修正します。
ブループリントはストアの識別情報、つまりアプリケーション ID と記録 ID の両方でデータに紐付けられます。読み込んだ .rrd は独自の識別情報を保持しているため、ストリームはその rrd の値から構築してください(両方を設定してください。設定しない場合、recording_id はランダムな値がデフォルトになります)。どちらかが一致しないと、ビューアーはブループリントとデータを別々の記録として扱い、ブループリントは適用されません。
import time
import rerun as rr
import rerun.blueprint as rrb
from rerun.chunk import RrdReader
from rerun.experimental import ViewerClient
store = RrdReader("segment.rrd").recordings()[0] # the rrd's application id + recording id
with ViewerClient.spawn(headless=True, port=9879) as viewer:
rec = rr.RecordingStream(store.application_id, recording_id=store.recording_id)
rec.connect_grpc(url=viewer.url)
rec.log_file_from_path("segment.rrd")
def shot(blueprint, path):
rec.send_blueprint(blueprint, make_active=True, make_default=True)
time.sleep(2) # let the import finish and a frame render; bump if a view is blank
viewer.save_screenshot(path) # view_id=view.id for a single view
shot(blueprint_v1, "bp_v1.png")
# Read bp_v1.png, revise, send the next one into the same viewer.
shot(blueprint_v2, "bp_v2.png")
完成したブループリントを組み込むには、rr.init / spawn / connect_grpc / save に default_blueprint= を渡すか、notebook_show に blueprint= を渡します。
注意点
DataframeViewはクエリがないと「タイムラインが不明」と表示されます:query=rrb.archetypes.DataframeQuery(timeline="<timeline>", apply_latest_at=True)。- ビューが空白に戻る場合、インポーターの処理がまだ終わっていない可能性があります(待機時間を延ばしてください)。または、カーソルがデータより前にある可能性があります(
rrb.TimePanel(play_state=rrb.components.PlayState.Following)を追加してください)。 rrbビューとViewerClient(rerun.experimental)は不安定です。コンストラクターの引数が拒否された場合は、help()を確認してください。
関連項目
rerun-data-model— エンティティ、アーキタイプ、タイムライン。rerun-catalog-queries— データセット内のエンティティを列挙します。