Learn R Programming

grip

grip (Graph dRawing with Intelligent Placement) is an R package for multiscale graph layout. Its primary unweighted and weighted workflows target 2D and 3D, while opt-in weighted-GRIP, metric-MDS, and edge-KK workflows also support higher-dimensional embeddings. The main workflow is:

  • grip(metric = "hop") for topology-first layouts,
  • grip(metric = "edge_length") when edge lengths define the graph metric,
  • compare.layouts() and score.layout() for real-data layout selection,
  • trace.grip() with the same metric choice 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).

Installation

# Install from GitHub
install.packages("remotes")
remotes::install_github("pgajer/grip")

Quick start

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")

Features

  • Multiscale force-directed layout in 2D and 3D via C++ (Rcpp).
  • A unified grip() interface for hop-metric and edge-length-metric layouts.
  • Opt-in multiscale weighted layout in dimensions greater than 3 via weighted.grip.nd(), with higher-dimensional metric-MDS and edge-KK workflows available through metric.mds() and edge.kk().
  • Layout comparison and quality scoring across seeds and parameter settings (compare.layouts(), score.layout()).
  • Multiscale trace diagnostics for both metrics via trace.grip().
  • Advanced public experimental geodesic-KK utilities for weighted-layout scoring and polish (prepare.geodesic.kk(), score.geodesic.kk(), prepare.landmark.geodesic.kk(), score.landmark.geodesic.kk()).
  • Synthetic graph-family helpers for benchmark and geometry-rich examples.
  • Handles disconnected graphs automatically (component packing).
  • Tuned presets for common graph families (see table below).
  • Static 3D projection for vignettes and reports (plot.layout(projection = "ortho"), project.3d()).

Presets

FamilyPresetTuned on
Rectangular grid or latticepreset = "mesh"8x8 and 12x12 meshes
Sierpinski carpetpreset = "carpet"Level 3 and 4 carpets
Tree-like graphpreset = "tree"Binary trees, depths 5 and 6
3D torus or cylinderpreset = "torus"Torus sizes 8x8 through 20x20

Presets set sensible defaults for the GRIP parameters. Any explicit argument you pass overrides the preset value.

Choosing a workflow

  • Start with grip(metric = "hop"), the default, when topology should define the multiscale hierarchy and graph neighborhoods.
  • Use grip(metric = "edge_length") when positive edge lengths should also define shortest-path distances, hierarchy construction, neighborhoods, and insertion anchors.
  • Use compare.layouts() and score.layout() when the graph is important enough to justify a candidate shortlist rather than a single run.
  • Use trace.grip() with the corresponding metric when you need to diagnose how a solve evolved.
  • Add GKK/LGKK only after you already have weighted candidate layouts and need geodesic-aware scoring or polish; these are advanced public experimental tools rather than the default starting point.

The historical argument names edge_weights and weight_list represent positive edge lengths, not connection strengths. With metric = "hop", supplied lengths set adjacent-edge force targets while standard GRIP hierarchy and neighborhood searches still count hops. With metric = "edge_length", the lengths also define weighted shortest paths throughout the multiscale engine and are median-normalized by default. See ?grip for the complete semantics and normalization options.

Gallery

trace.grip() records the multiscale refinement process from coarse placement through the final layout. Local Sierpinski carpet and triangle animations can be generated with make readme-assets; generated animations are intentionally kept outside Git history.

More examples

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)

Edge-length-metric 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 <- grip(
  adj_list = adj_list, weight_list = weight_list,
  metric = "edge_length", 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)")

Layout comparison

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")]

Documentation

The package ships with four core vignettes:

  • Getting Started with grip — the shortest path through the default unweighted workflow, with guidance on when to switch to weighted, trace, or comparison workflows.
  • Weighted Graph Layouts with grip — geometry-aware layouts, geodesic scoring, and 2D-versus-3D decisions for weighted graphs.
  • Choosing Layouts for Real Data — a step-by-step workflow using the Zachary karate club and Krackhardt kite examples, plus a larger weighted HMP/U01 case study.
  • Tracing and Diagnosing Layouts — frame-by-frame tracing for understanding how a solve evolves.

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.

Citation

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

License

GPL (>= 3)

Copy Link

Version

Install

install.packages('grip')

Version

0.2.0

License

GPL (>= 3)

Issues

Pull Requests

Stars

Forks

Maintainer

Pawel Gajer

Last Published

August 31st, 2026

Functions in grip (0.2.0)

graph_generators

Sample graph generators
grip-0.2-migration

Migrate code to the grip 0.2 API
grip-package

grip: Graph dRawing with Intelligent Placement
grip

Compute a GRIP layout
gripui_app

Build the `gripui` Shiny application
gripui_family_app

Build the graph-family geometry explorer Shiny application
globalrep.grip

Compute a GRIP layout with coarse global repulsion
graph.riemannian.star.structure

Build a local Riemannian star structure for Gram-gKK layouts
globalrep.weighted.grip

Compute a weighted geometry-aware GRIP layout
gripui_project_from_compare

Convert `compare.layouts()` output into a `gripui_project`
gripui_project_from_dir

Create a `gripui_project` from a directory of saved artifacts
gripui_validate_project

Validate a `gripui_project`
gripui_graph_family_catalog

Catalog of graph families for the geometry explorer app
hmp.gc

HMP Illumina 16S Giant-Component Graph
kernel.gram.gkk

Optimize a kernel Gram-gKK layout
gripui_project

Create a normalized `gripui` project object
kary_tree_weighted_graph_helpers

Intrinsically weighted k-ary tree helpers
irregular_torus_surface_helpers

Weighted irregular torus surface helpers
irregular_sphere_surface_helpers

Weighted irregular sphere surface helpers
irregular_shell_solid_helpers

Weighted irregular shell solid helpers
hmp.u01.gc.coarse

HMP/U01 Coarsened Giant-Component Graph
irregular_pair_of_pants_surface_helpers

Weighted irregular pair-of-pants surface helpers
irregular_annulus_surface_helpers

Weighted irregular annulus surface helpers
irregular_rectangle_surface_helpers

Irregular rectangle surface helpers
irregular_ball_solid_helpers

Weighted irregular ball solid helpers
irregular_double_torus_surface_helpers

Weighted irregular double-torus surface helpers
landmark.geodesic.kk

Optimize a layout under the landmark geodesic KK energy
porous_cube_surface_helpers

Weighted porous cube-mask surface helpers
occupied_mesh_surface_helpers

Occupied-mesh and perforated-grid helpers
plot.layout

Quick plot for graph layouts
perforated_grid_helpers

Deterministic perforated-grid occupancy helpers
misf.geodesic.kk

Optimize an embedding with the MISF-based geodesic-KK pipeline
prepare.edge.kk

Prepare an edge-only graph for edge-KK repair
metric.mds

Metric-MDS baseline layout for GMDS experiments
legacy.grip

Compute the legacy GRIP layout
mask_pattern_helpers

Mask pattern helpers for recursive grid families
mesh_surface_helpers

Weighted mesh surface helpers
menger_sponge_surface_helpers

Weighted Menger sponge surface helpers
params.from.summary

Extract layout parameters from a comparison summary row
prepare.geodesic.kk

Prepare full geodesic KK data for repeated layout evaluation
project.3d

Project 3D coordinates to 2D for static plotting
recursive_cube_mask_surface_helpers

Weighted recursive cube-mask surface helpers
prepare.graph.geodesic.mds

Prepare a graph-first geodesic-MDS path cache
recursive_triangle_mask_surface_helpers

Weighted recursive triangle-mask surface helpers
recursive_tetrahedron_mask_surface_helpers

Weighted recursive tetrahedron-mask surface helpers
prepare.landmark.geodesic.kk

Prepare sparse landmark-geodesic KK data for repeated layout evaluation
prepare.misf.geodesic.kk

Prepare a MISF-based multiscale geodesic-KK object
repulsive.stage

Optimize one pure repulsive layout stage
recursive_mask_grid_surface_helpers

Weighted recursive mask-grid surface helpers
sampled_rectangle_surface_helpers

Sampled rectangle surface helpers
score.layout

Score a single layout using graph-aware quality heuristics
repulsive.state

Evaluate a pure repulsive layout objective
sierpinski_carpet_surface_helpers

Weighted Sierpinski carpet surface helpers
run_gripui

Run the `gripui` Shiny application
score.misf.geodesic.kk

Score a MISF-based geodesic-KK fit
score.gmds

Score a layout with the common GMDS diagnostic panel
run_gripui_family

Run the graph-family geometry explorer Shiny application
score.geodesic.kk

Score a layout under the full geodesic KK energy
score.landmark.geodesic.kk

Score a layout under the landmark geodesic KK energy
sierpinski_tetrahedron_surface_helpers

Weighted Sierpinski tetrahedron surface helpers
sierpinski_triangle_surface_helpers

Weighted Sierpinski triangle surface helpers
triangle_mask_helpers

Triangle mask helpers for recursive gasket families
triangulated_pair_of_pants_surface_helpers

Weighted triangulated pair-of-pants surface helpers
trace.legacy.grip

Compute a trace for the legacy GRIP layout
trace.grip

Trace a GRIP layout
sphere_surface_helpers

Weighted sphere surface helpers
torus_surface_helpers

Weighted torus surface helpers
triangulated_annulus_surface_helpers

Weighted triangulated annulus surface helpers
tetrahedron_mask_helpers

Tetrahedron mask helpers for recursive gasket families
weighted.grip.nd

Weighted GRIP layout in arbitrary dimensions
triangulated_polyhedron_surface_helpers

Weighted triangulated polyhedron surface helpers
vicsek_surface_helpers

Weighted Vicsek surface helpers
cube_mask_pattern_helpers

Cube mask pattern helpers for recursive porous families
build.misf

Build a maximal independent set filtration (MISF) for a graph
edge.repulsive.stage

Optimize one edge-isometric repulsive unfolding stage
build.weighted.misf

Build a weighted MISF hierarchy
edge.repulsive.state

Evaluate an edge-isometric repulsive unfolding objective
edge.kk

Optimize an edge-KK local repair layout
compare.layouts

Compare multiple layout candidates across seeds
geodesic.kk

Optimize a layout under the full geodesic KK energy
cylinder_surface_helpers

Weighted cylinder surface helpers
edge.length.density.stiffness

Construct edge-length stiffnesses for edge-isometric GMDS layouts
geometry.diagnostics

Geometry-aware diagnostics against a canonical target