---
title: "Getting started with RGraphSpace"
author: "Sysbiolab Team"
date: "`r Sys.Date()`"
bibliography: bibliography.bib
output: 
  html_document:
    theme: cerulean
    self_contained: yes
    toc: true
    toc_float: true
    toc_depth: 2
    css: custom.css
vignette: >
  %\VignetteIndexEntry{RGraphSpace: igraph to ggplot2 graphics}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE, purl=FALSE}
knitr::opts_chunk$set(
  echo = TRUE,
  collapse = TRUE,
  comment = "#>",
  fig.align = "center",
  fig.width = 7,
  fig.height = 5,
  out.width="90%"
  )
```

<br/>
**Package**: RGraphSpace `r packageVersion('RGraphSpace')`

```{r clipboard, echo=FALSE, results='asis'}
if (!identical(Sys.getenv("IN_PKGDOWN"), "true")) {
  cat('<script src="clipboard.js"></script>')
}
```

# Overview

*RGraphSpace* is an R package that generates *ggplot2* graphics [@Wickham2016] for *igraph* objects [@Nepusz2006] within a normalized coordinate space. This is particularly useful when graph elements must be spatially aligned with reference frames. For comprehensive documentation and use cases, see the [online tutorials](https://sysbiolab.github.io/RGraphSpace/).

# Quick start

To get started, we load a toy `igraph` and plot it.

```{r Load packages for quick start, eval=TRUE, message=FALSE}
#--- Load required packages
library("RGraphSpace")
library("igraph")
library("ggplot2")
library("tidygraph")
```

```{r Quick start - 1, eval=TRUE, message=TRUE}
# Load the bundled toy igraph object
data("gtoy1", package = "RGraphSpace")

# The most direct call: pass an igraph to plotGraphSpace()
plotGraphSpace(gtoy1, node.labels = TRUE)
```

Next, we build this toy `igraph` from scratch to demonstrate the vertex and edge attributes that *RGraphSpace* parses automatically. This shows exactly what the package expects as input. We use `igraph`'s `make_star()` function with `V()` and `E()` to assign attributes. *RGraphSpace* requires that every vertex carries `x`, `y`, and `name` attributes.

```{r Toy igraph - 1, eval=TRUE, message=TRUE}
# Make a 'toy' igraph with 5 nodes and 4 edges;
# ..either a directed or undirected graph
gtoy1 <- make_star(5, mode = "out")

# Check whether the graph is directed or not
is_directed(gtoy1)

# Check graph size
vcount(gtoy1)

ecount(gtoy1)

# Assign 'x' and 'y' coordinates to each vertex;
# ..this can be an arbitrary unit in (-Inf, +Inf)
V(gtoy1)$x <- c(0, 2, -2, -4, -8)
V(gtoy1)$y <- c(0, 0,  2, -4,  0)

# Assign a name to each vertex
V(gtoy1)$name <- paste0("n", 1:5)
```

```{r Toy igraph - 2, eval=TRUE, message=FALSE}
# Plot the reconstructed 'gtoy1' using RGraphSpace
plotGraphSpace(gtoy1, node.labels = TRUE)
```

The same graph can be supplied as a *tidygraph* object; every *RGraphSpace* entry point accepts it through the same interface.

```{r Toy igraph - 3, eval=TRUE, message=FALSE}
# Same toy graph, as tidygraph
gr <- as_tbl_graph(gtoy1)
gr
```

```{r Toy igraph - 4, eval=TRUE, message=FALSE}
plotGraphSpace(gr, node.labels = TRUE)
```

If your graph has no pre-existing spatial coordinates, you can supply any *igraph* layout matrix directly via the `layout` argument of `GraphSpace()`, which assigns coordinates internally.

```{r Layout, eval=TRUE, message=FALSE}
# If your graph has no spatial coordinates, pass a layout directly:
set.seed(42)
GraphSpace(gtoy1, layout = igraph::layout_with_fr(gtoy1))
```

# *RGraphSpace* attributes

*RGraphSpace* provides two interfaces for styling nodes and edges: graph attributes (*camelCase* names such as `nodeFillColor` and `edgeColor`) and *ggplot2* mappings via `aes()`. The two interfaces coexist without collision; see the *Why camelCase attribute names?* section for details.

Next, we list all vertex and edge attributes that can be passed to *RGraphSpace* methods.

## Vertex attributes

```{r Node attributes, eval=TRUE, message=FALSE}
# Node fill color (Hexadecimal or color name)
V(gtoy1)$nodeFillColor <- c("red", "#00ad39", "grey80", "lightblue", "cyan")

# Node line color (Hexadecimal or color name)
V(gtoy1)$nodeLineColor <- "grey20"

# Node color; shorthand for both fill and line, overridden by either
# V(gtoy1)$nodeColor <- "grey80"

# Node transparency (in [0,1])
V(gtoy1)$nodeAlpha <- 1

# Node size (numeric in [0, 100], as '%' of the plot space)
V(gtoy1)$nodeSize <- c(8, 5, 5, 10, 5)

# Node shape (integer code between 0 and 25; see 'help(points)')
V(gtoy1)$nodeShape <- c(21, 22, 23, 24, 25)

# Node line width (as in 'lwd' standard graphics; see 'help(gpar)')
V(gtoy1)$nodeLineWidth <- 1

# Node labels ('NA' will omit the label)
V(gtoy1)$nodeLabel <- c("V1", "V2", "V3", "V4", NA)

# Node label size (in mm)
V(gtoy1)$nodeLabelSize <- 3

# Node label color (Hexadecimal or color name)
V(gtoy1)$nodeLabelColor <- "black"
```

## Edge attributes

Given a list of edges, *RGraphSpace* represents only one edge for each pair of connected vertices. If there are multiple edges connecting the same node pair, it will display the attributes of the first occurrence in the data.

```{r Edge attributes - 1, eval=TRUE, message=FALSE}
# Edge color (Hexadecimal or color name)
E(gtoy1)$edgeColor <- c("red","green","blue","black")

# Edge transparency (in [0,1])
E(gtoy1)$edgeAlpha <- 1

# Edge line width (as in 'lwd' standard graphics; see 'help(gpar)')
E(gtoy1)$edgeLineWidth <- 0.8

# Edge line type (as in 'lty' standard graphics; see 'help(gpar)')
E(gtoy1)$edgeLineType <- c("solid", "11", "dashed", "2124")
```

Note: `edgeLineColor` is deprecated as of version 1.4.3 and replaced by `edgeColor`.

## Arrowhead attributes

**Arrowhead in directed graphs**: By default, an arrow will be drawn for each edge according to its left-to-right orientation in the edge list (*e.g.* `A -> B`). If there are mutual connections, the package will recode the mutual edges to represent a bidirectional flow.

```{r Edge attributes - 2, eval=TRUE, message=FALSE}
# Arrowhead types in directed graphs
## Integer or character code:
## 0 = "---", 1 = "-->", -1 = "--|"
E(gtoy1)$arrowType <- 1
``` 

**Arrowhead in undirected graphs**: By default, no arrow will be drawn for undirected graphs. However, arrowheads may be assigned according to the coding below.

```{r Edge attributes - 3, eval=TRUE, message=FALSE}
# Arrowhead types in undirected graphs
## Integer or character code:
##  0 = "---"
##  1 = "-->",  2 = "<--",  3 = "<->",  4 = "|->"
## -1 = "--|", -2 = "|--", -3 = "|-|", -4 = "<-|"
gtoy1_undir <- igraph::as_undirected(gtoy1, edge.attr.comb = "first")
E(gtoy1_undir)$arrowType <- 1
# Note: in undirected graphs, this attribute overrides
# the edge's orientation in the edge list and adds arrowheads
# to edges that would otherwise be drawn without any
```

... and plot the fully attributed `gtoy1` object.
 
```{r A shortcut for RGraphSpace, eval=TRUE, message=FALSE}
# Plot the fully attributed 'gtoy1'
plotGraphSpace(gtoy1, node.labels = TRUE)
```

```{r, eval=FALSE, message=FALSE, echo=FALSE, include=FALSE, purl=FALSE}
# V(gtoy1)$nodeLabel <- c("V1", "V2", "V3", "V4", "V5")
# save(gtoy1, file = "./data/gtoy1.RData")
# tools::resaveRdaFiles(paths = "./data/gtoy1.RData")
```

# Passing graphs to *geoms*

Alternatively, an `igraph` can be converted to a `GraphSpace` object and passed directly to *ggplot2* geoms. This gives full access to the *ggplot2* layer system for combining graph elements with other plot types.

```{r Using geoms - 1, eval=TRUE, message=TRUE}
# Load the toy graph used in the previous example
data("gtoy1", package = "RGraphSpace")

# Create a GraphSpace object
gs <- GraphSpace(gtoy1)

# Normalize the coordinates
gs <- normalizeGraphSpace(gs)

gs
```

`normalizeGraphSpace()` maps all vertex coordinates to a `[0, 1]` unit interval. This step is handled automatically when passing an `igraph` to `plotGraphSpace()`; when building a plot layer by layer, it must be called explicitly.

```{r Using geoms - 2, eval=TRUE, message=FALSE}
# Build a layered ggplot2 graph
# geom_edgespace() draws edges; geom_nodespace() draws nodes
# aes(label = nodeLabel) maps the 'nodeLabel' vertex attribute to node labels
ggplot(gs) + 
  geom_edgespace() + 
  geom_nodespace(aes(label = nodeLabel)) + 
  theme_gspace_coords(is_norm = TRUE)
```

# Why *camelCase* attribute names?

The node and edge attribute names above (`nodeFillColor`, `nodeSize`, etc.) are deliberately distinct from their *ggplot2* counterparts (`fill`, `size`, etc.). This is not a stylistic choice, it is a functional boundary between two different aesthetic interfaces.

When a column in a data frame shares a name with a *ggplot2* aesthetic, *ggplot2* subjects it to scale training, which is designed for data-driven mappings. Graph attributes, however, carry **final, pre-defined values**  (hex color codes, fixed sizes, specific shapes) that must be applied as-is without modification. The *camelCase* names make these attributes invisible to the scale system. They are assigned to their corresponding *ggplot2* aesthetics only after this step is complete, preventing other `geoms` from mixing incompatible values (e.g. hex colors and numeric variables) into their scale training.

The practical consequence is that `V(g)$fill <- "red"` and `V(g)$nodeFillColor <- "red"` are **not** equivalent. The former is a regular user variable, available for data-driven mapping via `aes(fill = fill)`. The latter is a pre-defined identity value applied directly to the rendered nodes.

This design allows the two interfaces to coexist cleanly. When multiple sources define the same aesthetic, the following priority applies (highest to lowest):

Priority | Source | Description
:-------: | :------: | -----------
1 | Aesthetic mapping | Data-driven, scale-trained, shown in legends.
2 | Fixed parameter | Identity value applied uniformly to all nodes or edges.
3 | Graph attribute | Per-node or per-edge identity values from the `GraphSpace` object.

# Online tutorials

For detailed integration with the *ggplot2* ecosystem, see the online documentation available at:

* https://sysbiolab.github.io/RGraphSpace/

# Other examples

Vignettes illustrating how *RGraphSpace* can be used in combination with *PathwaySpace* to project network signals.

* https://sysbiolab.github.io/PathwaySpace/

# Citation

If you use *RGraphSpace*, please cite:

* Sysbiolab Team. "RGraphSpace: A lightweight interface between igraph and ggplot2 graphics." R package, 2023. Doi: 10.32614/CRAN.package.RGraphSpace

# Session information
```{r label='Session information', eval=TRUE, echo=FALSE}
sessionInfo()
```


# References

