Introduction to cograph

library(cograph)

Why cograph

R has several network packages — igraph for graph algorithms, qgraph for psychometric networks, tidygraph for dplyr-style manipulation. Each does one thing well but forces you into its own data format and API. Going from a raw matrix to a filtered, annotated, publication-ready figure typically means loading three packages, converting between formats, and writing boilerplate code to stitch the results together.

cograph was designed to eliminate that friction. Every function — plotting, centrality, community detection, filtering — accepts any major network format directly: matrices, edge lists, igraph, statnet, qgraph, and tna objects. No manual conversion. Centrality returns a tidy data frame, not a list of separate calls. Community detection is one function with 11 algorithms behind it. Statistical annotations (confidence intervals, p-values, significance stars) render directly on the figure. And when you need igraph or statnet for something cograph does not do, to_igraph() and to_network() convert back without data loss.

Beyond standard network analysis, cograph visualizes higher-order sequential pathways as simplicial blob diagrams, renders bootstrap stability results with forest plots (linear, circular, and grouped layouts), and performs motif analysis that identifies specific named node triples — not just abstract type counts.

The result is a single package that covers the full workflow from data import to publication-ready output, while remaining interoperable with the rest of the R network ecosystem.

set.seed(42)
n <- 10
states <- c("Explore", "Plan", "Monitor", "Adapt", "Reflect",
            "Discuss", "Synthesize", "Evaluate", "Create", "Share")
mat <- matrix(0, n, n, dimnames = list(states, states))
# Sparse: ~30% of edges populated
edges <- sample(which(row(mat) != col(mat)), 30)
mat[edges] <- round(runif(30, 0.05, 0.5), 2)

Plotting

splot() is the main plotting function. One call, publication-ready output.

splot(mat, tna_styling = TRUE, minimum = 0.1,
  title = "Learning Regulation Network")

Key parameters: layout, minimum, node_fill, node_size, edge_labels, curvature, scale_nodes_by, theme, tna_styling.

splot(mat, layout = "spring")
splot(mat, minimum = 0.1, edge_labels = TRUE)
splot(mat, scale_nodes_by = "betweenness")
splot(mat, theme = "dark")
splot(mat, tna_styling = TRUE)

Layouts: "oval", "spring", "circle", "grid", "mds", "star", "bipartite", "groups", or a custom coordinate matrix.

Themes: "default", "dark", "minimal", "gray", "nature", "colorblind", "viridis".

Node shapes: "circle", "square", "triangle", "diamond", "pentagon", "hexagon", "star", "heart", "ellipse", "cross", "rectangle", "pie", "donut", or custom SVG via register_svg_shape().

Specialized plots

Function Purpose
splot() Network graph (base R)
soplot() Grid/ggplot2 network
plot_tna() / tplot() TNA-style wrappers with qgraph-compatible parameters
plot_chord() Chord diagram (directed/undirected ribbons)
plot_heatmap() Adjacency heatmap with clustering
plot_ml_heatmap() Multi-layer comparison heatmap
plot_transitions() / plot_alluvial() Alluvial / Sankey flow diagrams
plot_trajectories() Individual trajectory tracking
plot_compare() Difference network between two matrices
plot_comparison_heatmap() Side-by-side heatmap comparison
plot_mixed_network() Directed + undirected edges combined
plot_bootstrap_forest() Bootstrap CI forest plots (linear, circular, grouped)
plot_edge_diff_forest() Edge difference plots (linear, circular, chord, tile)
plot_simplicial() Higher-order pathway blob overlays
overlay_communities() Community blob overlays on network
plot_mcml() Two-layer hierarchical cluster visualization
plot_mtna() Flat multi-cluster layout
plot_mlna() Stacked multilayer 3D perspective
plot_htna() Multi-group heterogeneous TNA layout
plot_robustness() Robustness degradation curves
plot_permutation() / plot_group_permutation() Permutation test results
plot_simplicial(mat,
  c("Explore Plan -> Monitor",
    "Monitor Adapt -> Reflect",
    "Discuss Synthesize -> Evaluate",
    "Create Share -> Explore"),
  dismantled = TRUE, ncol = 2,
  title = "Higher-Order Pathways")

Input formats

Every function accepts six formats directly.

Format Example
Matrix splot(mat)
Edge list splot(data.frame(from = "A", to = "B", weight = 1))
igraph splot(igraph::make_ring(5))
statnet splot(network::network(mat))
qgraph from_qgraph(q)
tna splot(tna::tna(data))

Conversion utilities:

Function Output
as_cograph(x) cograph_network object
to_igraph(x) igraph object
to_matrix(x) Adjacency matrix
to_data_frame(x) / to_df(x) Edge list data frame
to_network(x) statnet network object
from_qgraph(q) Extract qgraph styles into cograph

Filtering and selection

Filter edges and nodes with expressions. Centrality measures are lazy-computed inside filter_nodes().

strong <- filter_edges(mat, weight > 0.3)
get_edges(strong)
#>    from to weight
#> 1     8  3   0.33
#> 2    10  3   0.49
#> 3     8  4   0.43
#> 4    10  4   0.39
#> 5     1  5   0.35
#> 6     6  5   0.35
#> 7     7  5   0.42
#> 8     2  6   0.40
#> 9     4  6   0.34
#> 10    2  8   0.49
#> 11    9  8   0.39
#> 12    3  9   0.37
#> 13    2 10   0.36
top3 <- select_nodes(mat, top = 3, by = "betweenness")
get_labels(top3)
#> [1] "Plan"    "Monitor" "Adapt"
Function Purpose
filter_edges(x, ...) Filter by weight, from, to
filter_nodes(x, ...) Filter by degree, centrality, label
select_nodes(x, ...) Top-N by centrality, by name, neighbors
select_edges(x, ...) Top-N, involving, between, bridges, mutual
select_neighbors(x, of) Ego-network extraction (multi-hop)
select_component(x) Largest or named component
select_top(x, n, by) Top-N nodes by any centrality
select_bridges(x) Bridge edges only
select_top_edges(x, n) Top-N edges by weight
select_edges_involving(x, nodes) Edges touching specific nodes
select_edges_between(x, s1, s2) Edges between two node sets
subset_nodes(x, ...) / subset_edges(x, ...) Base R-style subsetting
simplify(x) Remove multi-edges and self-loops

Getters and setters:

Function Purpose
get_nodes(x) / set_nodes(x, df) Node data frame
get_edges(x) / set_edges(x, df) Edge data frame
get_labels(x) Node label vector
n_nodes(x) / n_edges(x) Counts
is_directed(x) Directedness
set_groups(x) / get_groups(x) Group assignments
set_layout(x, layout) Layout coordinates
summarize_network(x) Network summary

Centrality

centrality() computes node centrality measures and returns one tidy data frame. The built-in student_interactions edge list works directly: no igraph object, no matrix conversion, no setup code.

data(student_interactions)
centrality(student_interactions)
#>    node degree_all strength_all closeness_all betweenness  eigenvector
#> 1    Ac         33          129    0.01754386   26.342857 1.000000e+00
#> 2    Ad         20           36    0.01754386   42.541520 1.096110e-01
#> 3    Fi         24           51    0.01666667   35.721634 1.789565e-01
#> 4    Ik         14           24    0.01666667   25.844874 1.551369e-02
#> 5    Vx         26           43    0.01960784   90.717124 7.238902e-02
#> 6    Rt         20           37    0.01785714   63.135739 1.159931e-01
#> 7    Km         11           16    0.01639344   18.175108 2.804725e-02
#> 8    Gj         19           31    0.01818182  114.599049 3.265786e-02
#> 9    Bd         12           18    0.01612903   21.769264 9.607736e-03
#> 10   Ce         10           13    0.01612903   16.648629 4.473504e-03
#> 11   Oq         14           20    0.01754386   34.151726 2.293068e-02
#> 12   Ya         13           19    0.01612903   18.216122 1.758656e-02
#> 13   Mo         12           17    0.01587302   38.264502 1.003629e-01
#> 14   Hj         12           19    0.01754386   85.816522 2.013125e-02
#> 15   Tv         10           13    0.01666667   25.916306 1.320877e-02
#> 16   Eg         10           12    0.01639344   22.335171 5.783916e-03
#> 17   Pr         11           18    0.01666667   23.974060 7.602231e-02
#> 18   Qs         15           19    0.01785714   76.910851 1.511764e-02
#> 19   Xz         14           18    0.01639344   22.280159 8.533484e-03
#> 20   Np          8            8    0.01666667   12.044048 1.549052e-02
#> 21   Dg         13           13    0.01886792   29.240901 6.260099e-03
#> 22   Hk         16           25    0.01818182   72.176441 1.201845e-01
#> 23   Wy         11           16    0.01639344   34.014358 1.054705e-03
#> 24   Jl         15           18    0.01818182   67.359085 5.009801e-02
#> 25   Fh         21           55    0.01818182   78.588877 2.817489e-01
#> 26   Zb          7            8    0.01538462    9.583333 5.429715e-05
#> 27   Eh          7           13    0.01428571   34.325000 1.163185e-03
#> 28   Be         14           16    0.01851852  105.250898 2.203252e-03
#> 29   Df          8           10    0.01562500   11.026190 4.800876e-06
#> 30   Cf         12           15    0.01724138  119.109163 1.243207e-02
#> 31   Su          6            9    0.01369863   33.154401 1.028472e-04
#> 32   Ln          7            8    0.01408451    5.749708 1.376854e-02
#> 33   Gi          3            4    0.01351351    0.000000 1.280388e-17
#> 34   Uw          4            7    0.01250000    0.000000 6.480230e-20
#>       pagerank
#> 1  0.285861728
#> 2  0.052985644
#> 3  0.077591140
#> 4  0.024836857
#> 5  0.057364714
#> 6  0.042552472
#> 7  0.016655998
#> 8  0.025444498
#> 9  0.014321668
#> 10 0.010679742
#> 11 0.016087378
#> 12 0.016588876
#> 13 0.031180263
#> 14 0.019051413
#> 15 0.012644206
#> 16 0.010425091
#> 17 0.022794289
#> 18 0.019784870
#> 19 0.013229134
#> 20 0.008466679
#> 21 0.010345027
#> 22 0.040383192
#> 23 0.009067435
#> 24 0.020529375
#> 25 0.070538086
#> 26 0.005635780
#> 27 0.010080122
#> 28 0.009378924
#> 29 0.004957518
#> 30 0.017877547
#> 31 0.005136500
#> 32 0.007628879
#> 33 0.005483193
#> 34 0.004411765

That one call returns the default centrality table: degree, strength, closeness, betweenness, eigenvector centrality, and PageRank. Individual functions return named vectors when you want one measure only:

centrality_degree(student_interactions)
#> Ac Ad Fi Ik Vx Rt Km Gj Bd Ce Oq Ya Mo Hj Tv Eg Pr Qs Xz Np Dg Hk Wy Jl Fh Zb 
#> 33 20 24 14 26 20 11 19 12 10 14 13 12 12 10 10 11 15 14  8 13 16 11 15 21  7 
#> Eh Be Df Cf Su Ln Gi Uw 
#>  7 14  8 12  6  7  3  4
centrality_pagerank(student_interactions)
#>          Ac          Ad          Fi          Ik          Vx          Rt 
#> 0.285861728 0.052985644 0.077591140 0.024836857 0.057364714 0.042552472 
#>          Km          Gj          Bd          Ce          Oq          Ya 
#> 0.016655998 0.025444498 0.014321668 0.010679742 0.016087378 0.016588876 
#>          Mo          Hj          Tv          Eg          Pr          Qs 
#> 0.031180263 0.019051413 0.012644206 0.010425091 0.022794289 0.019784870 
#>          Xz          Np          Dg          Hk          Wy          Jl 
#> 0.013229134 0.008466679 0.010345027 0.040383192 0.009067435 0.020529375 
#>          Fh          Zb          Eh          Be          Df          Cf 
#> 0.070538086 0.005635780 0.010080122 0.009378924 0.004957518 0.017877547 
#>          Su          Ln          Gi          Uw 
#> 0.005136500 0.007628879 0.005483193 0.004411765

Selected measures:

Category Functions
Degree centrality_degree(), centrality_strength(), centrality_indegree(), centrality_outdegree(), centrality_instrength(), centrality_outstrength()
Path centrality_betweenness(), centrality_closeness(), centrality_harmonic(), centrality_eccentricity() (each with in/out variants)
Spectral centrality_eigenvector(), centrality_pagerank(), centrality_authority(), centrality_hub(), centrality_alpha(), centrality_power(), centrality_subgraph()
Structural centrality_coreness(), centrality_constraint(), centrality_transitivity(), centrality_laplacian()
Flow centrality_current_flow_closeness(), centrality_current_flow_betweenness(), centrality_load()
Spreading centrality_diffusion(), centrality_leverage(), centrality_kreach(), centrality_voterank(), centrality_percolation()

Edge centrality: edge_centrality(), edge_betweenness().

Network properties

network_summary() computes up to 37 network-level metrics.

network_summary(mat)
#>   node_count edge_count density component_count diameter mean_distance min_cut
#> 1         10         30   0.333               1     0.97         0.435       1
#>   centralization_degree centralization_in_degree centralization_out_degree
#> 1                 0.123                    0.333                     0.222
#>   centralization_betweenness centralization_closeness centralization_eigen
#> 1                      0.149                    0.238                0.479
#>   transitivity reciprocity assortativity_degree hub_score authority_score
#> 1        0.423       0.111               -0.116        NA              NA
Function Purpose
network_summary() 37 metrics (density, diameter, clustering, etc.)
network_small_world() Small-world coefficient
network_rich_club() Rich-club coefficient
network_global_efficiency() Global efficiency
network_local_efficiency() Local efficiency
degree_distribution() Degree histogram
network_girth() Shortest cycle
network_radius() Minimum eccentricity
network_bridges() Bridge edges
network_cut_vertices() Articulation points
network_vertex_connectivity() Minimum vertices to disconnect
network_clique_size() Largest complete subgraph

Community detection

11 algorithms with a consistent interface.

comms <- communities(mat, method = "walktrap")
comms
#> Community structure (walktrap)
#>   Nodes: 10  | Communities: 2  | Modularity: 0.1976 
#>   Sizes: 5, 5 
#> 
#>        node community
#>     Explore         1
#>        Plan         2
#>     Monitor         2
#>       Adapt         1
#>     Reflect         1
#>     Discuss         1
#>  Synthesize         1
#>    Evaluate         2
#>      Create         2
#>       Share         2
community_sizes(comms)
#> [1] 5 5
Function Algorithm Alias
community_louvain() Louvain modularity com_lv()
community_leiden() Leiden (improved Louvain) com_ld()
community_fast_greedy() Fast greedy com_fg()
community_walktrap() Random walk com_wt()
community_infomap() Information flow com_im()
community_label_propagation() Label propagation com_lp()
community_edge_betweenness() Edge betweenness com_eb()
community_leading_eigenvector() Leading eigenvector com_le()
community_spinglass() Spin glass com_sg()
community_optimal() Exact optimization com_op()
community_fluid() Fluid communities com_fl()

Additional community functions:

Function Purpose
community_consensus() Run algorithm N times, keep stable assignments
compare_communities() Compare partitions (NMI, VI, Rand, adjusted Rand)
modularity() Modularity score
community_sizes() Size of each community
color_communities() Color vector from community membership
cluster_quality() Quality metrics (silhouette, Dunn index)
cluster_significance() Permutation-based significance testing
detect_communities() Alternative interface (returns data frame)

Motifs

Motif analysis identifies recurring 3-node patterns using the MAN classification (16 directed triad types).

mot <- motifs(mat, significance = FALSE)
mot
#> Motif Census 
#> Level: aggregate | States: 10 | Pattern: triangle 
#> 
#> Type distribution:
#> 030T 120C 030C 120D 120U 
#>   11    3    2    2    1 
#> 
#> Top 5 results:
#>  type count
#>  030T    11
#>  120C     3
#>  030C     2
#>  120D     2
#>  120U     1
Function Purpose
motifs() MAN type census with significance testing
subgraphs() Named node triples forming each pattern
motif_census() Low-level triad census
extract_motifs() Per-individual motif extraction
extract_triads() Extract specific triad types
triad_census() Raw 16-type triad count
get_edge_list() Edge list from tna for motif input

Plot types: plot(mot, type = "types"), "significance", "triads", "patterns".

Robustness

Simulate network degradation under targeted and random removal.

robustness(mat, type = "vertex", measure = "betweenness", n_iter = 100)
plot_robustness(x = mat, measures = c("betweenness", "degree", "random"))
Function Purpose
robustness() Simulate removal attacks (vertex or edge)
plot_robustness() Plot robustness curves for multiple strategies
robustness_summary() AUC and summary statistics
robustness_auc() Area under the robustness curve

Disparity filter

Backbone extraction using the disparity filter (Serrano et al. 2009).

disparity_filter(mat)
splot.tna_disparity(disparity_filter(mat))

Multi-cluster visualization

clusters <- list(
  Cognitive  = c("Explore", "Plan", "Monitor", "Adapt", "Reflect"),
  Social     = c("Discuss", "Synthesize", "Share"),
  Evaluative = c("Evaluate", "Create")
)
plot_mcml(mat, clusters, mode = "tna")
plot_mtna(mat, clusters)
Function Architecture
plot_mcml() Two-layer: detail nodes + summary pies
plot_mtna() Flat cluster layout
plot_mlna() Stacked 3D multilayer
plot_htna() Multi-group heterogeneous TNA
csum() / summarize_clusters() Pre-compute cluster aggregation
as_tna() / as_mcml() Convert cluster summaries to tna objects
summarize_network() / cnet() Extract cluster-level network (matrix aggregation)

Multilayer networks

Construct and analyze supra-adjacency matrices for multilayer/multiplex networks.

Function Purpose
mlna() / supra_adjacency() Build supra-adjacency matrix
supra_layer() / supra_interlayer() Extract individual layers
aggregate_layers() / aggregate_weights() Combine layers
plot_mlna() 3D perspective visualization
plot_ml_heatmap() Multi-layer heatmap comparison

Higher-order networks

Detect sequential dependencies beyond first-order Markov models. Requires the Nestimate package.

Function Purpose
build_hon() Higher-Order Network construction
build_hypa() Path anomaly detection (hypergeometric null)
build_mogen() Multi-order model selection (AIC/BIC)
path_counts() k-step path frequencies
plot_simplicial() Visualize pathways as blob overlays
build_simplicial() Simplicial complex from cliques
persistent_homology() Topological persistence across thresholds
q_analysis() Multi-level structural connectivity
verify_simplicial() Cross-validate via Euler-Poincare theorem

TNA integration

Direct support for all tna package objects:

Object What splot() does
tna Network with donut rings, TNA styling
group_tna Multi-panel grid per group
tna_bootstrap Stability-styled edges
tna_permutation Colored difference network
group_tna_permutation Multi-panel permutation results
tna_disparity Backbone filter visualization

Palettes

Function Colors
palette_viridis(n) Viridis scale
palette_pastel(n) Soft pastel
palette_blues(n) Blue gradient
palette_reds(n) Red gradient
palette_diverging(n) Blue-white-red
palette_colorblind(n) Colorblind-safe
palette_rainbow(n) Rainbow

Pipe API

The sn_* functions provide a chainable builder for the grid/ggplot2 rendering path.

mat |>
  cograph() |>
  sn_layout("spring") |>
  sn_theme("minimal") |>
  sn_nodes(size = 8, fill = "steelblue") |>
  sn_edges(curvature = 0.2) |>
  sn_render(title = "My Network")

mat |> cograph() |> sn_save("network.pdf")
p <- mat |> cograph() |> sn_ggplot()
Function Purpose
cograph() / as_cograph() Create network object
sn_nodes() Node aesthetics
sn_edges() Edge aesthetics
sn_layout() Layout algorithm
sn_theme() Visual theme
sn_palette() Color palette
sn_render() Render to screen
sn_save() / sn_save_ggplot() Save to file
sn_ggplot() Convert to ggplot2 object
register_theme() / register_layout() / register_shape() Register custom themes, layouts, shapes

Further reading

Package resources:

Blog posts:

References: