Embedding Maps Trajectories#

Source: examples/embedding_maps_trajectories.py

Introduction#

Map ordered design traces into a shared coordinate space, then overlay their paths and scalar values so exploration behavior is visible instead of just the point cloud.

Technical Implementation#

  1. Build a tiny unified-table-like dataset with record IDs, trace IDs, steps, text, and performance values.

  2. Embed the text deterministically with a local lookup and build a PCA embedding map.

  3. Render a single value-colored trajectory map and a comparison grid; when no optional mapping backend is installed, compare PCA with a reflected PCA map so the plotting workflow still runs end to end.

  1from __future__ import annotations
  2
  3import importlib.util
  4from pathlib import Path
  5
  6import numpy as np
  7
  8import design_research_analysis as dran
  9
 10
 11def _local_embed(texts: list[str]) -> np.ndarray:
 12    lookup = {
 13        "seed concept": [0.0, 1.0, 0.0],
 14        "refined concept": [0.3, 0.9, 0.2],
 15        "prototype concept": [0.8, 0.4, 0.4],
 16        "alternate seed": [0.1, 0.2, 1.0],
 17        "alternate refinement": [0.2, 0.1, 0.8],
 18        "alternate prototype": [0.7, 0.3, 0.5],
 19    }
 20    return np.asarray([lookup[text] for text in texts], dtype=float)
 21
 22
 23def _comparison_methods() -> list[str]:
 24    if importlib.util.find_spec("umap") is not None:
 25        return ["pca", "umap"]
 26    if importlib.util.find_spec("sklearn") is not None:
 27        return ["pca", "tsne"]
 28    if importlib.util.find_spec("pacmap") is not None:
 29        return ["pca", "pacmap"]
 30    if importlib.util.find_spec("trimap") is not None:
 31        return ["pca", "trimap"]
 32    return ["pca"]
 33
 34
 35def main() -> None:
 36    """Build and plot trajectory-aware embedding maps."""
 37    rows = [
 38        {
 39            "record_id": "r1",
 40            "trace_id": "alpha",
 41            "step": 1,
 42            "text": "seed concept",
 43            "value": 0.2,
 44        },
 45        {
 46            "record_id": "r2",
 47            "trace_id": "alpha",
 48            "step": 2,
 49            "text": "refined concept",
 50            "value": 0.5,
 51        },
 52        {
 53            "record_id": "r3",
 54            "trace_id": "alpha",
 55            "step": 3,
 56            "text": "prototype concept",
 57            "value": 0.9,
 58        },
 59        {
 60            "record_id": "r4",
 61            "trace_id": "beta",
 62            "step": 1,
 63            "text": "alternate seed",
 64            "value": 0.1,
 65        },
 66        {
 67            "record_id": "r5",
 68            "trace_id": "beta",
 69            "step": 2,
 70            "text": "alternate refinement",
 71            "value": 0.4,
 72        },
 73        {
 74            "record_id": "r6",
 75            "trace_id": "beta",
 76            "step": 3,
 77            "text": "alternate prototype",
 78            "value": 0.8,
 79        },
 80    ]
 81
 82    embedded = dran.embed_records(rows, embedder=_local_embed)
 83    pca_map = dran.build_embedding_map(
 84        embedded.embeddings,
 85        method="pca",
 86        record_ids=embedded.record_ids,
 87    )
 88
 89    methods = _comparison_methods()
 90    if len(methods) > 1:
 91        comparison_maps = dran.compare_embedding_maps(
 92            embedded.embeddings,
 93            methods=methods,
 94            record_ids=embedded.record_ids,
 95            n_neighbors=3,
 96            perplexity=2.0,
 97        )
 98    else:
 99        comparison_maps = {
100            "pca": pca_map,
101            "pca_reflected": dran.EmbeddingMapResult(
102                coordinates=np.column_stack(
103                    [pca_map.coordinates[:, 0], -pca_map.coordinates[:, 1]]
104                ),
105                record_ids=list(pca_map.record_ids),
106                method="pca_reflected",
107                config={"derived_from": "pca"},
108            ),
109        }
110
111    output_dir = Path("artifacts/examples")
112    output_dir.mkdir(parents=True, exist_ok=True)
113
114    single_path = output_dir / "embedding_map.png"
115    grid_path = output_dir / "embedding_map_grid.png"
116
117    figure, _ = dran.plot_embedding_map(
118        pca_map,
119        rows,
120        trace_column="trace_id",
121        order_column="step",
122        value_column="value",
123        title="PCA trajectory map",
124    )
125    figure.savefig(single_path, dpi=150, bbox_inches="tight")
126    figure.clf()
127
128    grid_figure, _ = dran.plot_embedding_map_grid(
129        comparison_maps,
130        rows,
131        trace_column="trace_id",
132        order_column="step",
133        value_column="value",
134    )
135    grid_figure.savefig(grid_path, dpi=150, bbox_inches="tight")
136    grid_figure.clf()
137
138    print(f"Single map: {single_path}")
139    print(f"Comparison grid: {grid_path}")
140    print(f"Methods: {list(comparison_maps)}")
141
142
143if __name__ == "__main__":
144    main()

Expected Results#

Run Command

PYTHONPATH=src python examples/embedding_maps_trajectories.py

Writes artifacts/examples/embedding_map.png and artifacts/examples/embedding_map_grid.png, then prints the method names included in the comparison.

References#

  • docs/workflows_embedding_maps.rst