Skip to contents

A useful layout reveals graph structure while keeping distance distortion and sensitivity to initialization in view. This guide compares a small set of settings on 494_bus, a 494-vertex power network supplied with grip. Its source electrical values are not layout distances: we use the bundled unit-length connectivity graph.

Start with metric.mds(backend="sgd") for a graph-distance embedding. When full pairwise distances and fitting exceed the available resources, use metric.mds(backend="sgd", approximation="sparse"); sparse mode approximates the fitting objective and still needs independent distance-fidelity checks. Do not append edge-KK automatically: improving adjacent-edge lengths can worsen longer-range distance fidelity. This starting recommendation is not a claim that one optimizer wins on every graph.

Choose a method for the question

Question Starting point
Explore graph connectivity grip(metric='hop')
Respect positive traversal lengths grip(metric='edge_length')
Fit all shortest-path distances directly metric.mds(); SGD is the default backend
Reduce the cost of full MDS metric.mds(approximation='sparse')
Adjust edge lengths of an existing drawing edge.kk(coords=...), followed by independent scoring

The function overview explains input conventions and provides the complete categorized catalog. Metric MDS compares its two optimizers; weighted layouts explains distance-valued edges.

Compare alternative GRIP settings across seeds

g <- suitesparse.graph('494_bus')
cmp <- compare.layouts(edges=g$edges,n=g$n,dim=3,
  candidates=c('default','tree','mesh'),seeds=1:3,
  sample.size.stress=2000L,sample.size.nonedge=3000L,
  edge.crossings='never',return.layouts=TRUE)
knitr::kable(cmp$summary[,c('candidate','sampled.stress.mean',
  'edge.length.cv.mean','sampled.nonedge.sep.ratio.mean',
  'stability.procrustes.mean')],digits=3)
candidate sampled.stress.mean edge.length.cv.mean sampled.nonedge.sep.ratio.mean stability.procrustes.mean
mesh 0.277 0.192 0.322 0.370
default 0.291 0.282 0.411 0.389
tree 0.353 0.648 0.053 0.198

This section demonstrates an alternative algorithm, not the default SGD workflow. These are three GRIP presets with three seeds each. They are a teaching comparison, not tuned recommendations for power networks. Sampled stress is smaller when drawn distances better match graph shortest paths. Stability summarizes how much layouts vary after alignment. Use the same scoring samples and definitions across candidates.

494_bus: three GRIP presets, seed 1 in every view. Rigid alignment; no resizing.

The figure always shows seed 1; the table summarizes all three seeds. Rotate and switch presets to inspect branches and crowded regions. Neither the matrix nor these layouts provide a known geographical reference.

Select settings without hiding variability

cmp$runs retains the individual runs. A good average should be considered alongside variation among seeds and any unsuccessful attempts.

knitr::kable(cmp$runs[,intersect(c('candidate','seed','status','sampled.stress'),
                               names(cmp$runs))],digits=3)
candidate seed status sampled.stress
default 1 ok 0.262
default 2 ok 0.294
default 3 ok 0.317
tree 1 ok 0.349
tree 2 ok 0.402
tree 3 ok 0.309
mesh 1 ok 0.287
mesh 2 ok 0.242
mesh 3 ok 0.301

Use params.from.summary() to recover a candidate’s settings. If further improvement matters, try a small neighborhood of those settings and retain the initial comparison as a separate result. A composite score ranks candidates within its chosen criteria and weights; it is not a universal quality grade.

Choose an appropriate score

What matters? Function What the score means
Overall graph-distance agreement score.layout() Sampled drawn distances versus graph shortest paths, with fitted scale
Edge, route, and endpoint errors separately score.gmds() Distinct residuals with an explicit scale policy
Locations of corresponding vertices score.coordinates() Vertex displacement after the requested alignment
Shape of an already aligned triangular surface score.surface() Area-weighted surface distance; does not align the surfaces

Score the original 3D coordinates, not their 2D projection. An improvement in edge lengths can accompany worse distances between distant vertices. Likewise, a close surface overlay does not establish recovery of corresponding vertices. See the score definitions for units, alignment choices, and the differences between these quantities.

For graphs with meaningful labels, examine those labels alongside the geometry. The HMP/U01 case study illustrates this with biological community labels. Label separation alone does not establish accurate geometry.

Keep computation proportional to the question

Full MDS requires dense distances. Use estimate.preparation() before a large preparation; its matrix-size estimate is a lower bound, not peak memory. Start with a few seeds and candidates. Use traces to investigate a fold or collapse before increasing a search indiscriminately.

The layout-engine comparison illustrates common diagnostics for multiscale GRIP, igraph and graphlayouts on unweighted graphs. Those results do not benchmark the current metric-MDS backend.