grip (Graph dRawing with Intelligent Placement) is an R package for multiscale graph layout in 2D and 3D. The main workflow is:
grip() for unweighted graphs,weighted.grip() for weighted graphs,compare.layouts() and score.layout() for
real-data layout selection,trace.grip() and trace.weighted.grip() for
diagnostics.The package also includes advanced public experimental geodesic-KK utilities for weighted-layout scoring and polish. It builds on the GRIP method described in Gajer & Kobourov (2002) and Gajer, Goodrich & Kobourov (2004).
# Install from GitHub
install.packages("remotes")
remotes::install_github("pgajer/grip")library(grip)
# Lay out a small mesh in 2D using the "mesh" preset
edges <- edges.mesh(8, 8)
coords <- grip(edges, n = 64, dim = 2, preset = "mesh", seed = 1)
plot.layout(coords, edges, pch = 16, cex = 0.6, main = "8x8 mesh")grip() for unweighted graphs.weighted.grip() for weighted graphs.compare.layouts(),
score.layout()).trace.grip(), trace.weighted.grip()).prepare.geodesic.kk(),
score.geodesic.kk(),
prepare.landmark.geodesic.kk(),
score.landmark.geodesic.kk()).plot.layout(projection = "ortho"),
project.3d()).rgl.| Family | Preset | Tuned on |
|---|---|---|
| Rectangular grid or lattice | preset = "mesh" |
8x8 and 12x12
meshes |
| Sierpinski carpet | preset = "carpet" |
Level 3 and 4 carpets |
| Tree-like graph | preset = "tree" |
Binary trees, depths 5 and 6 |
| 3D torus or cylinder | preset = "torus" |
Torus sizes 8x8 through
20x20 |
Presets set sensible defaults for the GRIP parameters. Any explicit argument you pass overrides the preset value.
grip() when the graph is unweighted.weighted.grip() when the graph is
weighted.compare.layouts() and score.layout()
when the graph is important enough to justify a candidate shortlist
rather than a single run.trace.grip() or trace.weighted.grip()
when you need to diagnose how a solve evolved.The animations below show the multiscale refinement process captured
by trace.grip(). Starting from a coarse global placement,
the algorithm iteratively refines vertex positions until the layout
converges.


Edge-list input (2D, circle placement)
edges <- edges.cycle(18)
coords <- grip(edges, n = 18, dim = 2, placement = "circle", seed = 2)
plot.layout(coords, edges, pch = 16, cex = 0.7)Weighted adjacency list (geometry-aware)
adj_list <- list(c(2), c(1, 3), c(2, 4), c(3))
weight_list <- list(c(1.0), c(1.0, 2.0), c(2.0, 1.5), c(1.5))
coords <- weighted.grip(adj_list = adj_list, weight_list = weight_list,
n = 4, dim = 2, seed = 12)
plot.layout(coords)3D layout with static projection
edges <- edges.torus(8, 12)
coords <- grip(edges, n = max(edges), dim = 3, preset = "torus", seed = 3)
plot.layout(coords, edges, projection = "ortho", main = "Torus (8x12)")For real-world graphs without a known target layout,
compare.layouts() compares candidates across seeds and
reports quality metrics. Use params.from.summary() to
extract the winning parameters for reuse.
edges <- edges.mesh(10, 10)
cmp <- compare.layouts(edges, n = 100, dim = 2,
candidates = c("default", "mesh"),
seeds = 1:3)
cmp$summary[, c("candidate", "score.composite", "sampled.stress.mean")]The package ships with four core vignettes:
The pkgdown site also includes companion articles such as the interactive explorer guide, the HMP/U01 object-structure note, the comparison article, and the synthetic-family gallery.
The geodesic-KK helpers are public and documented in the reference index, but they are intentionally positioned as advanced experimental tools layered on top of the main weighted workflow.
If you use grip in published work, please cite the underlying algorithm:
Gajer, P. and Kobourov, S.G. (2002). GRIP: Graph dRawing with Intelligent Placement. Journal of Graph Algorithms and Applications, 6(3), 203–224. doi: 10.7155/jgaa.00052
Gajer, P., Goodrich, M.T. and Kobourov, S.G. (2004). A multi-dimensional approach to force-directed layouts of large graphs. Computational Geometry, 29(1), 3–18. doi: 10.1016/j.comgeo.2004.03.014
GPL (>= 3)