cograph

The easiest way to go from network data to publication-ready visualization in R. One function plots any network. One pipe does everything. No boilerplate, no format wrangling — just pass your data and get results.

6 Input Formats 25 Centrality Measures 11 Community Algorithms 12+ Node Shapes Pipe-Friendly API Full TNA Integration
6
Input Formats
25
Centrality Measures
11
Community Algorithms
10+
Network Properties
12+
Plot Types
7
Built-in Themes

Import & Convert

as_cograph() · to_igraph() · to_matrix() · to_data_frame()

Filter & Select

filter_edges() · filter_nodes() · select_nodes() · select_edges()

Centrality

centrality() · centrality_degree() · centrality_pagerank() · …25 total

Communities

communities() · community_louvain() · community_leiden() · …11 total

Plotting

splot() · soplot() · plot_chord() · plot_heatmap() · plot_transitions()

Pipe API

sn_nodes() · sn_edges() · sn_layout() · sn_theme() · sn_render()

Installation

# From CRAN (core plotting features)
install.packages("cograph")

# Development version from GitHub (full feature set described below)
devtools::install_github("sonsoleslp/cograph")
library(cograph)
Note: The full feature set described on this page — centrality functions, community detection, network properties, filtering/selection utilities, and specialized plots — is available in the GitHub development version. The CRAN release includes the core plotting engine. Install from GitHub to access everything.

1. Universal Network Import

No format conversion needed. Pass a matrix, edge list, igraph, statnet, qgraph, or tna object to any cograph function and it just works. Directionality is auto-detected from matrix symmetry or the source object — override with directed = TRUE/FALSE when needed.

FormatTypeAuto-detect
matrixSquare adjacency or weight matrixSymmetric → undirected
data.frameEdge list with from, to, weight columnsDirected
igraphigraph objectFrom object
networkstatnet network objectFrom object
qgraphqgraph object (full style extraction)From object
tnatna, group_tna, ctna, ftna, atna objectsDirected
Example: From adjacency matrix
mat <- matrix(c(
  0.0, 0.4, 0.2,
  0.3, 0.0, 0.3,
  0.2, 0.3, 0.0
), 3, 3, byrow = TRUE)
rownames(mat) <- colnames(mat) <- c("A", "B", "C")

# Any function accepts matrices directly
splot(mat)
centrality(mat)
communities(mat)
Example: From edge list
edges <- data.frame(
  from = c("A", "A", "B", "C"),
  to   = c("B", "C", "C", "A"),
  weight = c(0.5, 0.3, 0.8, 0.2)
)

splot(edges)
centrality(edges)
Example: From igraph
library(igraph)
g <- make_graph("Zachary")

splot(g)
centrality(g, measures = c("degree", "betweenness"))
communities(g, method = "louvain")
Example: From qgraph (full style extraction)
library(qgraph)
q <- qgraph(mat)

# Extracts layout, colors, shapes, edge styles — everything
from_qgraph(q)

Conversion Utilities

Convert freely between formats. All converters accept any of the six input types.

FunctionOutput
as_cograph(x)cograph_network object (pipe-ready)
to_igraph(x)igraph object
to_matrix(x)Adjacency / weight matrix
to_data_frame(x)Edge list data frame
to_network(x)statnet network object
Example: Round-trip conversion
library(igraph)
g <- make_graph("Zachary")

# igraph → matrix → cograph_network → back to igraph
mat <- to_matrix(g)
net <- as_cograph(mat)
g2  <- to_igraph(net)

2. Pipe-Friendly Network Utilities

Manipulate networks with expressive, chainable functions that read like English. All accept any input format and return the same format by default — so you can pipe a matrix through filters and straight into splot(). Set keep_format = TRUE to preserve igraph/matrix types when needed.

filter_edges() & filter_nodes()

NSE (non-standard evaluation) filters — use column names directly in expressions, just like dplyr::filter().

FunctionAvailable Variables
filter_edges(x, ...)weight, from, to
filter_nodes(x, ...)degree, label, id
Example: Filter edges by weight
# Keep only strong edges
splot(filter_edges(mat, weight > 0.3))

# Pipe-friendly
mat |>
  filter_edges(weight > 0.3) |>
  splot()
Example: Filter nodes by degree
# Keep high-degree nodes
mat |>
  filter_nodes(degree >= 3) |>
  splot()

# Combine edge and node filters
mat |>
  filter_edges(weight > 0.3) |>
  filter_nodes(degree >= 2) |>
  splot()

select_nodes() & select_edges()

Advanced selection with built-in centrality computation, community-aware filtering, top-N selection, neighborhood expansion, and component extraction — all in one function.

FunctionKey Features
select_nodes(x, ...)NSE filter, top, by (any centrality), neighbors_of, component
select_edges(x, ...)NSE filter, top, by, involving, between, bridges_only, mutual_only
select_neighbors(x, of)Ego-network extraction (multi-hop)
select_component(x)Largest or named component
select_top(x, n)Top-N nodes by any centrality
select_bridges(x)Bridge edges only
select_top_edges(x, n)Top-N edges by weight or betweenness
select_edges_involving(x)Edges touching specific nodes
select_edges_between(x)Edges between two node sets
Example: Top nodes by centrality
# Top 5 nodes by PageRank
mat |>
  select_nodes(top = 5, by = "pagerank") |>
  splot()

# Top 3 by betweenness, expand to neighbors
mat |>
  select_nodes(top = 3, by = "betweenness") |>
  splot()
Example: Community-aware edge selection
# Edges within the same community
mat |>
  select_edges(same_community) |>
  splot()

# Bridge edges (connect different components)
mat |>
  select_bridges() |>
  splot()
Example: Ego-network extraction
# 2-hop neighborhood of node "A"
mat |>
  select_neighbors(of = "A", order = 2) |>
  splot()

Getters, Setters & Groups

FunctionPurpose
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 check
set_groups(x, ...)Assign layers / clusters / groups
get_groups(x)Retrieve current groupings
set_layout(x, layout)Set layout coordinates

3. Centrality & Network Properties

25 Node Centrality Measures

One call to centrality(x) computes all 25 measures and returns a tidy data frame. Or use individual functions like centrality_degree(x) for a named vector. Each function has its own focused help page — no digging through irrelevant parameters.

CategoryMeasuresDirectional
Degreecentrality_degree(), centrality_strength()in / out / all
Path-basedcentrality_betweenness(), centrality_closeness(), centrality_harmonic(), centrality_eccentricity()in / out / all
Spectralcentrality_eigenvector(), centrality_pagerank(), centrality_authority(), centrality_hub(), centrality_alpha(), centrality_power(), centrality_subgraph()
Structuralcentrality_coreness(), centrality_constraint(), centrality_transitivity(), centrality_laplacian()
Flowcentrality_current_flow_closeness(), centrality_current_flow_betweenness(), centrality_load()
Spreadingcentrality_diffusion(), centrality_leverage(), centrality_kreach(), centrality_voterank(), centrality_percolation()in / out / all

Directional measures also have shorthand functions: centrality_indegree(), centrality_outstrength(), centrality_incloseness(), etc.

Example: Compute all centralities
# All 25 measures at once
centrality(mat)

# Specific measures, sorted
centrality(mat,
  measures = c("degree", "betweenness", "pagerank"),
  sort_by = "pagerank",
  digits = 3
)
Example: Individual centrality functions
# Each returns a named numeric vector
centrality_degree(mat)
#> A B C
#> 4 3 5

centrality_pagerank(mat, damping = 0.9)
#>     A     B     C
#> 0.35  0.28  0.37

# Directional shorthands
centrality_instrength(mat)
centrality_outdegree(mat)
Example: Scale nodes by centrality in plots
# Node size proportional to PageRank
splot(mat, scale_nodes_by = "pagerank")

# Directional shorthand + dampening
splot(mat,
  scale_nodes_by = "instrength",
  scale_nodes_scale = 0.5,
  node_size_range = c(3, 12)
)

Edge Centrality

Example: Edge betweenness
# All edge measures
edge_centrality(mat)

# Find bridge edges
edge_centrality(mat, sort_by = "betweenness")

# Named vector shorthand
edge_betweenness(mat)

Network-Level Properties

FunctionWhat it Measures
network_summary(x)Comprehensive summary: density, reciprocity, transitivity, diameter, components, …
network_small_world(x)Small-world coefficient (sigma, omega)
network_rich_club(x)Rich-club coefficient (degree-normalized)
network_global_efficiency(x)Global communication efficiency
network_local_efficiency(x)Local fault tolerance
network_girth(x)Shortest cycle length
network_radius(x)Minimum eccentricity
network_vertex_connectivity(x)Minimum vertices to disconnect
network_clique_size(x)Largest clique size
network_cut_vertices(x)Articulation points
network_bridges(x)Bridge edges
degree_distribution(x)Degree distribution with optional plot
Example: Network summary
network_summary(mat)
#> ── Network Summary ──
#> Nodes: 8 | Edges: 24 | Directed: TRUE
#> Density: 0.429 | Reciprocity: 0.833
#> Transitivity: 0.612 | Diameter: 3
#> Components: 1 | Mean degree: 6.0

4. Community Detection

11 Algorithms + Consensus

One unified interface: communities(x, method = "louvain"). Or call each algorithm directly. Every result is a cograph_communities object you can print(), plot(), extract membership() from, or pass to splot() — no igraph wrangling required.

AlgorithmFunctionShortBest For
Louvaincommunity_louvain()com_lvLarge networks, general use
Leidencommunity_leiden()com_ldBetter quality than Louvain
Fast Greedycommunity_fast_greedy()com_fgMedium networks
Walktrapcommunity_walktrap()com_wtClear community structure
Infomapcommunity_infomap()com_imDirected networks, flow
Label Propagationcommunity_label_propagation()com_lpVery large, speed-critical
Edge Betweennesscommunity_edge_betweenness()com_ebSmall, hierarchical
Leading Eigenvectorcommunity_leading_eigenvector()com_leDominant structure
Spinglasscommunity_spinglass()com_sgNegative weights allowed
Optimalcommunity_optimal()com_opExact solution (<50 nodes)
Fluidcommunity_fluid()com_flKnown number of communities
Consensuscommunity_consensus()com_consensusRobust, multi-run agreement
Example: Detect and inspect communities
library(igraph)
g <- make_graph("Zachary")

# Via dispatcher
comm <- communities(g, method = "louvain")
print(comm)
#> Community detection: louvain
#> Communities: 4 | Modularity: 0.42
#> Sizes: 12  6  5  11

# Direct function
comm2 <- community_fast_greedy(g)

# Short alias
comm3 <- com_wt(g)  # walktrap

# Extract results
membership(comm)
n_communities(comm)
community_sizes(comm)
modularity(comm)

Consensus & Comparison

Example: Consensus community detection
# Run Louvain 100 times, build consensus
comm <- community_consensus(g,
  method = "louvain",
  n_runs = 100,
  threshold = 0.5
)

# Compare two community structures
compare_communities(comm, comm2, method = "nmi")
Example: Visualize communities
# Automatic community coloring
comm <- community_louvain(g)
plot(comm)  # dispatches to splot with community colors

# Or manually with color_communities()
splot(g, node_fill = color_communities(comm))

5. Rich Plotting Functions

splot() & soplot()

splot(mat) — that's it. One function, any format, publication-ready output. Customize with 80+ parameters for nodes, edges, labels, donuts, pies, and more. soplot() provides the same interface via grid/ggplot2 for layered composition.

Example: Node shapes, donuts, and pies
# Mixed node shapes
splot(mat,
  node_shape = c("circle", "hexagon", "diamond", "square", "star"),
  node_fill = c("#E63946", "#457B9D", "#2A9D8F", "#E9C46A", "#F4A261"),
  layout = "circle"
)

# Donut charts (outer ring = proportion)
splot(mat,
  donut_fill = c(0.9, 0.7, 0.5, 0.3, 0.8),
  donut_color = "steelblue"
)

# Pie charts (inner segments)
splot(mat,
  node_shape = "pie",
  pie_values = list(c(0.5, 0.3, 0.2), c(0.4, 0.4, 0.2), ...),
  pie_colors = c("#E63946", "#457B9D", "#2A9D8F")
)

# Donut + Pie combo
splot(mat,
  donut_fill = c(0.95, 0.87, 0.72),
  donut_color = "#2E7D32",
  donut_show_value = TRUE,
  pie_values = prob_vals,
  pie_colors = c("#1976D2", "#FFA000", "#C62828")
)
Example: Edge styling
splot(mat,
  curvature = 0.3,
  arrow_size = 0.5,
  edge_width = 3,
  edge_color = "#546E7A",
  edge_start_style = "dotted",
  edge_labels = TRUE,
  threshold = 0.05
)
Example: Labels and fonts
splot(mat,
  label_size = 1.1,
  label_fontface = "bold",
  label_color = "#1A237E",
  label_position = "below"
)

Specialized Plot Types

FunctionVisualization
splot()Network graph (nodes + edges)
soplot()Grid-based network (ggplot2 layering)
plot_chord()Chord diagram with arcs and ribbons
plot_heatmap()Matrix heatmap with clustering support
plot_ml_heatmap()Multi-layer comparison heatmaps
plot_transitions()Alluvial / Sankey flow diagrams
plot_alluvial()Alias for plot_transitions()
plot_trajectories()Individual tracking flows
plot_compare()Difference network (two matrices)
plot_comparison_heatmap()Side-by-side heatmap comparison
plot_permutation()Permutation test results
plot_mixed_network()Mixed network types
Example: Chord diagram
plot_chord(mat,
  segment_colors = c("#E63946", "#457B9D", "#2A9D8F"),
  ticks = TRUE,
  tick_labels = TRUE
)
Example: Heatmap
plot_heatmap(mat,
  show_values = TRUE,
  color_palette = "viridis",
  cluster_list = list(
    Group1 = c("A", "B"),
    Group2 = c("C", "D", "E")
  )
)
Example: Alluvial / transition flow
# From transition matrices
plot_transitions(list(mat1, mat2, mat3))

# Individual tracking from data frame
df <- data.frame(T1 = c("A","B","A"), T2 = c("B","A","C"), T3 = c("C","C","B"))
plot_trajectories(df)

Themes, Shapes & Layouts

7 built-in themes: "default", "dark", "minimal", "gray", "nature", "colorblind", "viridis"

12+ node shapes: "circle", "square", "triangle", "diamond", "pentagon", "hexagon", "ellipse", "heart", "star", "cross", "rectangle", "pie", plus custom SVG shapes

Layout algorithms: "oval", "circle", "spring", "fr", "kk", "grid", "star", "bipartite", "groups", or any custom coordinate matrix

Example: Custom theme and layout
# Dark theme for presentations
splot(mat, theme = "dark", layout = "circle")

# Register a custom theme
register_theme("my_theme", list(
  node_fill = "#264653",
  node_border_color = "white",
  edge_color = "#2a9d8f",
  background = "#0f172a"
))
splot(mat, theme = "my_theme")

# Register a custom layout
register_layout("my_layout", function(n, ...) {
  cbind(x = cos(seq(0, 2*pi, length.out = n+1)[1:n]),
        y = sin(seq(0, 2*pi, length.out = n+1)[1:n]))
})

6. Pipe-Friendly Plotting API

For users who prefer building visualizations incrementally, the sn_* family provides a fully chainable pipe API. Each function modifies the network object and passes it along — readable, composable, and easy to extend.

The sn_* Workflow

StepFunctionPurpose
1cograph(x) or as_cograph(x)Create the network object
2sn_nodes(...)Set node size, shape, fill, labels, donuts, pies
3sn_edges(...)Set edge color, width, arrows, curvature, labels
4sn_layout("...")Choose layout algorithm
5sn_theme("...")Apply a visual theme
6sn_palette("...")Set color palette
7sn_render() / splot()Render to screen
sn_save("file.pdf")Save to file
sn_ggplot()Convert to ggplot object
Example: Full pipe workflow
mat |>
  cograph(layout = "circle") |>
  sn_nodes(
    fill = c("#E63946", "#457B9D", "#2A9D8F", "#E9C46A", "#F4A261"),
    shape = "hexagon",
    size = 5
  ) |>
  sn_edges(
    color = "weight",
    width = "weight",
    curvature = 0.3
  ) |>
  sn_theme("minimal") |>
  sn_palette("viridis") |>
  splot(title = "My Network")
Example: Save to file
mat |>
  cograph() |>
  sn_nodes(fill = "steelblue") |>
  sn_save("network.pdf", width = 8, height = 8)

# Or get a ggplot object for further customization
p <- mat |>
  cograph() |>
  sn_ggplot()
p + ggplot2::labs(title = "Custom title")

7. Complete TNA Integration

cograph is the official visualization engine for the tna package. Just call splot(fit) on any TNA model — transition matrices, initial probabilities, edge labels, arrow styles, and layout are all configured automatically. Every TNA object type is supported: tna, group_tna, ctna, ftna, atna, bootstrap results, and permutation tests.

Direct Plotting

Example: One-liner TNA visualization
library(tna)
library(cograph)

fit <- tna(engagement)

# One line — layout, arrows, edge labels, donut fills all auto-configured
splot(fit)

# Customize on top of TNA defaults
splot(fit,
  layout = "circle",
  node_shape = "hexagon",
  theme = "dark",
  scale_nodes_by = "instrength"
)
Example: Group TNA
# Group-level TNA models
gfit <- group_tna(engagement, group = engagement$Group)

# Plot each group
splot(gfit)

# Comparison heatmap across groups
plot_heatmap(gfit)
Example: TNA with centrality scaling
fit <- tna(engagement)

# Node size by in-strength (which states are transitioned TO most)
splot(fit, scale_nodes_by = "instrength")

# Combine with donut showing initial probabilities
splot(fit,
  donut_fill = fit$initial_probs,
  donut_color = "#1976D2",
  donut_show_value = TRUE,
  scale_nodes_by = "outstrength",
  layout = "circle"
)

Bootstrap & Permutation Testing

Example: Bootstrap visualization
library(tna)
fit <- tna(engagement)

# Bootstrap analysis
boot <- bootstrap(fit, iter = 1000)

# Dedicated S3 method — network with CI-based styling
splot(boot)
Example: Permutation test visualization
# Permutation test between two groups
perm <- permutation_test(gfit)

# Dedicated visualization
splot(perm)

# Or use the specialized plot function
plot_permutation(perm)
Example: Alluvial transitions from TNA data
# Visualize state transitions as alluvial flows
plot_transitions(fit)

# Individual trajectory tracking
plot_trajectories(fit$data)