sankey: Draw a Sankey plot for a network and estimated flows

View source: R/ui_plotting.R

sankeyR Documentation

Draw a Sankey plot for a network and estimated flows

Description

Draw a Sankey plot for a network and estimated flows

Usage

sankey(
  topo,
  nodes = NULL,
  flows = NULL,
  layout = NULL,
  new = TRUE,
  debug = FALSE,
  node_f = 1,
  edge_f = 1,
  node_s = "auto",
  edge_n = 32,
  cex_lab = NULL,
  cex.lab = NULL,
  fit = TRUE
)

Arguments

topo

A topology.

nodes

Optional, a tibble containing the properties of the nodes. It should have a 'comp' column with the same entries as the topology. It cannot have 'x' and 'y' entries. If it has a 'label' entry, it will replace the 'comp' values for node labels.

flows

A tibble containing the values of the flows in the topology. If NULL (the default), all flows have same width in the plot.

layout

String, node-placing algorithm to use from the ggraph package (e.g. "stress"). The ggraph package itself uses some algoritms from the igraph package. See the Details in the help of layout_tbl_graph_igraph for available algorithms. The ggraph package must be installed for this argument to be taken into account. Currently, only the "left2right" and "stress" layout are implemented in detail, and any other layout will use rough defaults for the aesthetic adjustments. Other layouts which are kind of working are "kk", "lgl", "fr", "dh", "mds". Some of those produce non-reproducible node locations (at least I haven't managed to reproduce them even by setting the RNG seed before calling the function).

new

Boolean, create a new page for the plot?

debug

Boolean, if TRUE then draw a lot of shapes to help with debugging.

node_f, edge_f

Multiplicative factor to adjust node and edge size.

node_s

String defining how node size is calculated. The effect of the string also depends on the chosen layout.

edge_n

Integer, number of interpolation points along each edge.

cex_lab, cex.lab

Expansion factor for label size (both arguments are synonyms).

fit

Boolean, if TRUE try to fit all the graphical elements inside the canvas.

Value

Mostly called for its side effect (plotting), but also returns invisible the scene object describing the Sankey plot. Note that the structure of this object is experimental and might change in the future!

Examples

library(magrittr)

topo <- topo(trini_mod)
sankey(topo, debug = TRUE)
sankey(topo, layout = "stress")
sankey(topo(aquarium_mod), layout = "stress", edge_f = 0.5)

m <- new_networkModel() %>%
    set_topo(c("subs -> NH3 -> subs",
               "NH3 -> Q, E", "E -> Q -> E",
               "E -> D, M")) %>%
    set_steady("subs") %>%
    set_prop_family("normal_sd")
ggtopo(m)
sankey(topo(m), layout = "stress")

# Debug visualization

## Helper functions
flows_from_topo <- function(x) {
    x <- unclass(x) # Remove the "topo" class to treat it as a matrix
    n_comps <- ncol(x)
    links <- which(x > 0)
    from <- links %/% n_comps + 1
    to <- links %% n_comps
    links <- tibble::tibble(from = from, to = to)
    for (i in seq_len(nrow(links))) {
        if (links$to[i] == 0) {
            links$from[i] <- links$from[i] - 1
            links$to[i] <- n_comps
        }
        stopifnot(x[links$to[i], links$from[i]] > 0)
    }
    flows <- tibble::tibble(from = colnames(x)[links$from],
                            to = rownames(x)[links$to])
    return(flows)
}
nodes_from_topo <- function(x) {
    nodes <- tibble::tibble(comp = colnames(x),
                            label = colnames(x))
    return(nodes)
}

t <- topo(trini_mod)
nodes <- nodes_from_topo(t)
nodes$label <- as.list(nodes$label)
nodes$label[[2]] <- latex2exp::TeX("$\\beta$")
nodes$size <- runif(nrow(nodes), 1, 2)
flows <- flows_from_topo(t)
flows$width <- runif(nrow(flows), 0.2, 2)
z <- sankey(t, nodes = nodes, flows = flows, layout = "left2right",
            debug = TRUE, node_f = 1, edge_f = 0.9, edge_n = 32,
            cex_lab = 1.5)

# Stress layout
y <- new_networkModel() %>%
        set_topo(c("subs -> NH3 -> subs",
                   "NH3 -> Q, E", "E -> Q -> E",
                   "E -> D, M")) %>%
        set_steady("subs") %>%
            set_prop_family("normal_sd")
y <- topo(y)
nodes <- nodes_from_topo(y)
nodes$size <- runif(nrow(nodes), 1, 10)
ggtopo(y, edge = "fan")
flows <- flows_from_topo(y)
flows$width <- runif(nrow(flows), 0.2, 5)
z <- sankey(y, nodes = nodes, flows = flows, debug = FALSE, edge_n = 32,
            edge_f = 0.4, node_s = "prop")

# Another example
r <- new_networkModel() %>%
    set_topo("infusion -> plasma -> body -> plasma") %>%
    set_steady(c("infusion", "body"))
r <- topo(r)
ggtopo(r, edge = "fan")
sankey(r, debug = TRUE, edge_f = 0.2)


isotracer documentation built on Sept. 22, 2023, 1:07 a.m.