library(readr)
library(dplyr)
library(igraph)
library(ggraph)

Dataset

A social network between dolphins:

  1. nodes
  2. edges

Create graph

# read edges and nodes
nodes = read_csv("dolphin_nodes.csv")
edges = read_csv("dolphin_edges.csv")
n = nrow(nodes)
m = nrow(edges)

# mutate edges and nodes
edge_type = sample(c("love", "friendship"), m, replace = TRUE)
edge_weight = runif(m, 1, 10)
edges = mutate(edges, type = edge_type, weight = edge_weight)
nodes = mutate(nodes, id = 1:n) %>% select(id, everything())

# degree of nodes (number of ties for each dolphin)
tb = tibble(v = c(1:n, edges$x, edges$y))
d = count(tb, v)$n - 1
nodes = mutate(nodes, degree = d)

# create graph from data frames
g = graph_from_data_frame(edges, directed = FALSE, nodes)

Mappings

lay = create_layout(g, layout = "fr")

# plot with ggraph
ggraph(lay) + 
  geom_edge_link() + 
  geom_node_point() +
  theme_graph()

# set theme to graph
set_graph_style()

# unset graph theme 
# unset_graph_style()

# add node names
ggraph(lay) + 
  geom_edge_link() + 
  geom_node_point() + 
  geom_node_text(aes(label = name), repel=TRUE)

# add edge type
ggraph(lay) + 
  geom_edge_link(aes(color = type)) + 
  geom_node_point()

# add node sex
ggraph(lay) + 
  geom_edge_link(aes(color = type)) + 
  geom_node_point(aes(shape = sex)) 

# plot node degree as node size
ggraph(lay) + 
  geom_edge_link(edge_colour = "grey") + 
  geom_node_point(aes(size = degree), colour = "black") 

# plot node degree as node size and alpha
ggraph(lay) + 
  geom_edge_link(edge_colour = "grey") + 
  geom_node_point(aes(size = degree, alpha = degree), colour = "black") 

# plot edge weight as edge alpha
ggraph(lay) + 
  geom_edge_link(aes(alpha = weight)) + 
  geom_node_point() 

Faceting

# facet edges
ggraph(lay) + 
  geom_edge_link(aes(color = type)) + 
  geom_node_point() +
  facet_edges(~type)

# facet nodes
ggraph(lay) + 
  geom_edge_link() + 
  geom_node_point(aes(color = sex)) +
  facet_nodes(~sex)

# facet nodes and edges
ggraph(g) + 
  geom_edge_link() + 
  geom_node_point() +
  facet_graph(type~sex) + 
  th_foreground(foreground = 'grey', border = TRUE)

Directed graphs

package <- data.frame(
  name = c("igraph", "ggraph", "dplyr", "ggplot", "tidygraph")
)

tie <- data.frame(
  from = c("igraph", "igraph", "ggplot", "igraph", "dplyr", "ggraph"),
  to =   c("ggraph", "tidygraph", "ggraph", "tidygraph", "tidygraph", "tidygraph")
)

g = graph_from_data_frame(tie, directed = TRUE, vertices = package)

# use arrows for directions
ggraph(g, layout = 'graphopt') + 
    geom_edge_link(aes(start_cap = label_rect(node1.name), end_cap = label_rect(node2.name)), 
                   arrow = arrow(type = "closed", length = unit(3, 'mm'))) + 
    geom_node_text(aes(label = name)) +
  theme_graph()

g2 = graph_from_data_frame(edges, directed = TRUE, nodes)

# Use edge alpha to indicate direction, direction is from lighter to darker node
ggraph(g2) +
  geom_edge_link(aes(alpha = stat(index)), show.legend = FALSE) +
  geom_node_point()  +
  theme_graph()

Hierarchical layouts

# flare class hierarchy
graph = graph_from_data_frame(flare$edges, vertices = flare$vertices)

# dendrogram
ggraph(graph, layout = 'dendrogram') + 
  geom_edge_diagonal()

# circular dendrogram
lay = create_layout(graph, layout = 'dendrogram', circular = TRUE)
head(lay)
##                        x         y  leaf          name size shortName
## flare         0.00000000 0.0000000 FALSE         flare    0     flare
## flare.animate 0.08994744 0.4918429 FALSE flare.animate    0   animate
## flare.data    0.31413145 0.3890006 FALSE    flare.data    0      data
## flare.display 0.60676275 0.4408389 FALSE flare.display    0   display
## flare.flex    0.63666587 0.3964298 FALSE    flare.flex    0      flex
## flare.physics 0.68222400 0.3115613 FALSE flare.physics    0   physics
##               ggraph.orig_index circular ggraph.index
## flare                       252     TRUE            1
## flare.animate               224     TRUE            2
## flare.data                  227     TRUE            3
## flare.display               228     TRUE            4
## flare.flex                  229     TRUE            5
## flare.physics               230     TRUE            6
ggraph(lay) + 
  geom_edge_diagonal() + 
  geom_node_point(aes(filter = leaf)) + 
  coord_fixed()

# rectangular tree map
ggraph(graph, layout = 'treemap', weight = 'size') + 
  geom_node_tile(aes(fill = depth), size = 0.25)

# circular tree map
ggraph(graph, layout = 'circlepack', weight = 'size') + 
  geom_node_circle(aes(fill = depth), size = 0.25, n = 50) + 
  coord_fixed()

# icicle
ggraph(graph, layout = 'partition') + 
  geom_node_tile(aes(y = -y, fill = depth))

# sunburst (circular icicle)
ggraph(graph, layout = 'partition', circular = TRUE) +
  geom_node_arc_bar(aes(fill = depth)) +
  coord_fixed()