Most graph-layout functions return only the final coordinate matrix. That is enough for plotting, but it hides the most useful diagnostic information:
The trace.grip() API makes those questions visible
through the same metric choice as grip():
trace.grip(metric = "hop") for combinatorial
layouts,trace.grip(metric = "edge_length") for edge-length
geometry-aware layouts.The example below traces a planar recursive triangle. Its nested
holes make the multiscale construction visible. Using
trace = "level" keeps the vignette readable by recording
the coarse initialization, the start of each new level, and the final
layout.
mesh.edges <- edges.sierpinski.triangle(4)
mesh.trace <- trace.grip(
mesh.edges,
n = max(mesh.edges),
dim = 2,
preset = "carpet",
rounds = 48,
final.rounds = 96,
trace = "level",
diagnostics = "light",
seed = 1
)
knitr::kable(mesh.trace$meta)| frame | phase | level_index | misf_level | round_in_level | active_vertices |
|---|---|---|---|---|---|
| 1 | init | 1 | 2 | 0 | 28 |
| 2 | level_start | 2 | 1 | 0 | 37 |
| 3 | level_start | 3 | 0 | 0 | 123 |
| 4 | final | 3 | 0 | 96 | 123 |
knitr::kable(mesh.trace$diagnostics[, c(
"frame",
"edge.length.cv",
"median.edge.length",
"sampled.nonedge.sep.ratio"
)], digits = 3)| frame | edge.length.cv | median.edge.length | sampled.nonedge.sep.ratio |
|---|---|---|---|
| 1 | NA | NA | NA |
| 2 | NA | NA | NA |
| 3 | 0.344 | 32.022 | 0.653 |
| 4 | 0.213 | 28.522 | 1.511 |
Each recorded stage has an ivue viewer showing its active vertices
and edges. Drag to rotate or scroll to zoom. Original planar coordinates
are retained at z = 0; each viewer fits its own bounds, so apparent size
across stages is not a measure of expansion. When ivue is
unavailable, a planar stage selector shows the same recorded vertices
and edges with common bounds across stages.
The two most useful tables are:
meta, which explains where each frame came from,diagnostics, which tracks simple quality signals frame
by frame.When you need more detail, trace = "round" records
intermediate refinement rounds within each active level.
mesh.trace.round <- trace.grip(
mesh.edges,
n = max(mesh.edges),
dim = 2,
preset = "carpet",
rounds = 6,
final.rounds = 8,
trace = "round",
trace.every = 4,
diagnostics = "light",
seed = 1
)
data.frame(
trace_mode = c("level", "round"),
n.frames = c(length(mesh.trace$frames), length(mesh.trace.round$frames))
)
#> trace_mode n.frames
#> 1 level 4
#> 2 round 8Use:
trace = "level" for most reporting and teaching,trace = "round" when you are diagnosing a tuning
issue.Early frames contain only the active coarse vertices. Read changes in the score together with the stage and active graph; adjacent frames may not score identical vertex sets. Level traces show insertion stages; round traces show more of the refinement within each stage. They are different sampling schedules.
For a weighted graph, use
trace.grip(metric='edge_length', ...) with its lengths. The
weighted guide explains this
metric. Detailed construction animations and their reproduction commands
are described in the asset
guide.
A trace object is more than a list of pictures. It can support:
The most useful components are:
final: the final coordinate matrix,frames: the stored coordinate frames,meta: frame provenance,diagnostics: per-frame metrics,lgkk.polish: optional post-layout LGKK result when
enabled as an advanced experimental refinement step.trace = "level" and
diagnostics = "light".trace = "round" only when you need finer-grained
diagnostics.target.coords when a meaningful geometric target
exists.For an API map, see Finding your way around grip. For reproducible bundles and reference scoring, see Graph examples. These guides and the interactive-explorer walkthrough are installed vignettes.
Getting Started with grip gives the short overview of
the main APIs.Weighted Graph Layouts with grip focuses on weighted
solving and scoring.Choosing Layouts for Real Data shows how trace fits
into a real-data selection workflow.