Source: vector_plot · vector_plot.md · updated 2026-07-10 · 🔒 secret gist

Synced verbatim from gist.github.com/bl9.

Build a single-file HTML tool (vanilla JS + Chart.js from CDN, no build step) called vector-profile-viewer.html that visualizes recommendation embeddings against a base vector.

image

Input

The tool accepts JSON via (a) a file picker and (b) a paste-in textarea. Schema:

{ "metadata": { "dim": 512, "metric": "cosine", // "cosine" | "l2" | "dot" "model": "optional-model-name", "normalized": true // whether vectors are already L2-normalized }, "base": { "label": "User profile (avg of history)", "vector": [0.012, -0.034, ...] // length must equal metadata.dim }, "items": [ { "id": "item-8841", "label": "Item title", "score": 0.9612, // similarity returned by the ANN engine "vector": [0.011, -0.029, ...] } // ... up to ~50 items ] }

Validate on load: all vectors match metadata.dim, no NaNs, items non-empty. Show clear error messages, never a blank page.

Processing

  1. If metadata.normalized is false OR any vector norm deviates from 1.0 by more than 1%, L2-normalize all vectors before plotting and show a notice ("vectors were normalized for display").
  2. Recompute cosine similarity of every item to the base locally; if it differs from the provided score by > 0.01, flag that item in the UI (helps catch metric mismatches with the ANN engine).
  3. Sort dimensions by the base vector's value (argsort). All plots use this shared column/x order.
  4. Rank items by recomputed similarity, descending.

Views (tabs or stacked sections)

View 1 — Sorted line profile (default)

  • X axis: dimension rank 1..dim (sorted by base value), label it as such.
  • Dark 2.5px line: base vector.
  • Gray band (fill, ~18% opacity): per-dimension min/max envelope across all items.
  • Highlighted lines: closest item (solid green #1baf7a), median item (dashed blue #2a78d6), farthest item (dotted red #e34948). 1.75px.
  • Dropdown to swap any highlighted slot for a specific item by label.
  • Toggle: raw values vs rolling-mean smoothing (window 5), default raw, state shown on the axis label.
  • Y axis: auto-fit to data with 10% padding; if normalized, expect ~±0.15. If any |component| > 5x the median absolute value, list those dims as "outlier dimensions" below the chart instead of letting them flatten it, with a toggle to clip them from the y-range.
  • Custom HTML legend above the chart (small squares + labels + sim scores), not Chart.js's default legend. Dash patterns must appear in the legend.

View 2 — Delta heatmap

  • Canvas, one row per item (ranked by similarity, best on top), one 1px column per dimension (same sorted order).
  • Cell value = item[d] − base[d]; diverging colormap blue↔gray↔red centered at 0, symmetric scale from the 99th percentile of |delta|.
  • Row labels: "#rank · label · sim". Hover tooltip: dim index (original, pre-sort), base value, item value, delta.

View 3 — Summary

  • Ranked horizontal lollipop chart of similarity to base.
  • Stat tiles: n items, mean sim, min sim, mean pairwise sim among items (redundancy indicator).

General

  • Everything client-side, no network calls except the Chart.js CDN.
  • Include a "Load demo data" button that generates a synthetic base + 20 items with decaying similarity so the tool works before real data is wired in.
  • Include an "Export PNG" button per chart and "Copy processed JSON" (with recomputed sims and sort order) for downstream use.
  • Clean, minimal styling; must be readable in light and dark OS themes.