ggtangle: Draw Network with Data
Author: Guangchuang Yu School of Basic Medical Sciences, Southern Medical University
Date: 2026-04-22

## Simple Network Visualization

    library(yulab.utils)
    library(igraph)
    library(ggplot2)
    library(ggtangle)
    library(aplot)
    library(ggfun)

    net <- sample_gnp(10, .5)

    V(net)$name = letters[1:10]
    E(net)$weight = abs(rnorm(length(E(net))))
    E(net)$type = sample(LETTERS[1:3], length(E(net)), replace=TRUE)

    p <- ggplot(net) + geom_edge()
    p

## Node color and size

    p1 <- p + geom_point(size=6, color='steelblue')
    p2 <- p + geom_point(aes(color = label %in% letters[1:5]), size=6)
    p3 <- p + geom_point(aes(size = igraph::degree(net)), color='steelblue')
    p4 <- p + geom_point(aes(shape = label %in% letters[1:5]), color='steelblue', size=8)

    plot_list(p1, p2, p3, p4, ncol=2)

## Node label

    p5 <- p + geom_label(aes(label=label, color=label %in% letters[1:5]), size=5)

    p6 <- p + geom_label(aes(label=label), size=5, data=ggtree::td_filter(label %in% letters[1:5]))

    plot_list(p5, p6)

## Edge

    p7 <- ggplot(net) + geom_edge(aes(linewidth=weight))
    p8 <- ggplot(net) + geom_edge(aes(color=type))
    p9 <- ggplot(net) + geom_edge(aes(linetype=type))

    plot_list(p7, p8, p9, ncol=3)

## Layouts

### Circular Layout

    ggplot(net, layout='circular') + geom_edge() + geom_point(size=5, color='blue')

### Linear Layout

    # Create a random graph
    set.seed(123)
    g <- sample_pa(20)
    V(g)$degree <- degree(g)
    V(g)$name <- as.character(1:20)

    # Plot with default linear layout
    p1 <- ggplot(g, layout = "linear") +
        geom_edge(geom=geom_curve) +
        geom_point() +
        ggtitle("Default Linear")

    # Plot with sorted linear layout
    p2 <- ggplot(g, layout = "linear", sort.by = "degree") +
        geom_edge(geom=geom_curve) +
        geom_point(aes(size = degree)) +
        ggtitle("Sorted Linear (by degree)")

    plot_list(p1, p2, ncol=1)

## Network with external data

    set.seed(123)
    expr <- abs(rnorm(10))
    d <- data.frame(label=V(net)$name, expression=expr)
    p %<+% d + geom_point(aes(color = expression), size=6) +
        scale_color_viridis_c()

## Network with pies

    flow_info <- data.frame(from = LETTERS[c(1,2,3,3,4,5,6)],
                            to = LETTERS[c(5,5,5,6,7,6,7)])

    dd <- data.frame(
        label = LETTERS[1:7],
        v1 = abs(rnorm(7)),
        v2 = abs(rnorm(7)),
        v3 = abs(rnorm(7))
    )

    g <- igraph::graph_from_data_frame(flow_info)

    p <- ggplot(g, layout='kk')  + geom_edge()

    library(scatterpie)

    scatterpie v0.2.6 Learn more at https://yulab-smu.top/

    p %<+% dd +
        geom_scatterpie(cols = c("v1", "v2", "v3")) +
        geom_text(aes(label=label), nudge_y = .2) +
        coord_fixed()

## Category-Item association plot

    set.seed(123)
    x <- list(A = letters[1:10], B=letters[5:12], C=letters[sample(1:26, 15)])

    p1 <- cnetplot(x, node_label = "none",
              color_category='firebrick', color_item='steelblue')
    p2 <- cnetplot(x, node_label = "all", size_category=2)
    p3 <- cnetplot(x, node_label = "category")
    p4 <- cnetplot(x, node_label = "item")
    p5 <- cnetplot(x, node_label = "share")
    p6 <- cnetplot(x, node_label = "exclusive")

    plot_list(p1, p2, p3, p4, p5, p6, ncol=3, tag_levels = 'A')

`node_label` can be selected items/genes to specify which genes to be labelled and can also used to subset the graph.

    g1 <- cnetplot(x, node_label = letters[1:5])

    options(cnetplot_subset = TRUE)
    g2 <- cnetplot(x, node_label = letters[1:5])

    plot_list(g1, g2)

    set.seed(123)
    d <- setNames(rnorm(26), letters)

    # color items/genes with associated data
    p7 <- cnetplot(x, foldChange=d) +
        scale_color_gradient2(name='associated data', low='darkgreen', high='firebrick')

    # filter items/genes by log2FC values to label
    p8 <- cnetplot(x, foldChange=d, node_labe = ">1") +
        scale_color_gradient2(name='associated data', low='darkgreen', high='firebrick')

    # Highlight categories
    p9 <- cnetplot(x, foldChange=d, hilight=c("B", "C")) +
        scale_color_gradient2(name='associated data', low='darkgreen', high='firebrick')

    # label in separate layer allows more detail adjustment
    p10 <- cnetplot(x, node_label="none")
    p10 <- p10 + geom_cnet_label(node_label = 'all', fontface='bold')
    plot_list(p7, p8, p9, p10, ncol=2, tag_levels = 'A')