Do reach out with ideas and collaborations!
(I’m busy but very interested in making cool stuff!)
Declaractive visualization based on a graphic grammar
# Plot data
# |
ggplot(diamonds) +
# representation Mapping to scales Setting to constants
# | | |
geom_point(aes(x = carat, y = price, colour = cut), alpha = 0.3) +
# Statistical transformation
# |
geom_density_2d(aes(x = carat, y = price), stat = 'density2d') +
# Scale specification
# |
scale_colour_brewer(type = 'qual') +
# Data subsetting/splitting
# |
facet_wrap(~color) +
# Styling
# |
theme_bw()
Opinionated at a cost
Before v2 | After v2 |
---|---|
Sort of doable | Build in |
In v2.1
In v2.2
A whole ecosystem has emerged - keep track of it on https://www.ggplot2-exts.org
Some highlights:
What is relational data?
Everything can be relational!
ggraph is not the only game in town:
But…
… ggraph offers a very powerful grammar extensions that is not limited to node-edge diagrams.
Key concepts:
Mapping between hierarchical structure and position of nodes
Also for non-obvious cases
Often drives the interpretation of the network…
… But be careful
For more hairball critic read Martin Krzywinski justification of hive plots
In ggraph the layouts are defined as part of the setup:
gr <- erdos.renyi.game(10, 0.5)
gr_p <- ggraph(gr, 'igraph', algorithm = 'kk')
… or created beforehand
layout <- createLayout(gr, 'igraph', algorithm = 'kk')
gr_p <- ggraph(data = layout)
The connection between entities
Often a line of some sort
Not necessarily needed
Edges comes in many types
geom_edge_link()
geom_edge_loop()
geom_edge_fan()
geom_edge_diagonal()
geom_edge_elbow()
… and flavors
geom_edge_link()
geom_edge_link2()
geom_edge_link0()
… and some are layout specific
geom_edge_arc()
geom_edge_hive()
gr <- graph_from_data_frame(highschool)
p <- ggraph(gr, 'igraph', algorithm = 'kk')
p + geom_edge_link()
p + geom_edge_arc()
p + geom_edge_fan()
p + geom_edge_fan0(arrow = arrow(length = unit(0.3, 'cm')))
p + geom_edge_fan(aes(colour = factor(year), alpha = ..index..)) +
scale_edge_alpha(guide = 'edge_direction')
hr <- as.dendrogram(hclust(dist(iris[, 1:4]), 'ward.D2'))
p <- ggraph(hr, 'dendrogram')
p + geom_edge_link()
p <- ggraph(hr, 'dendrogram', repel = TRUE)
p + geom_edge_link()
p + geom_edge_elbow()
p + geom_edge_diagonal()
# Set class of node to the class of it's children they are of equal class
hr <- treeApply(hr, function(node, children, ...) {
if (is.leaf(node)) {
attr(node, 'nodePar') <- list(species=iris[as.integer(attr(node, 'label')),5])
attr(node, 'nodePar')$class <- attr(node, 'nodePar')$species
} else {
classes <- lapply(children, attr, which = 'nodePar')
classes <- unique(sapply(classes, `[[`, 'class'))
if (length(classes) == 1 && !anyNA(classes)) {
attr(node, 'nodePar')$class <- classes
} else {
attr(node, 'nodePar')$class <- NA
}
}
node
}, direction = 'up')
p <- ggraph(hr, 'dendrogram', repel = TRUE)
p <- p + geom_edge_diagonal2(aes(colour = node.class), gEdges('long', nodePar = 'class'))
p
The entities that are connected.
Often points and/or labels. Size and colour often used to show node qualities
geom_node_point()
geom_node_text()
Layouts can introduce new node types:
geom_node_treemap()
Don’t go crazy with colour!
p <- p + geom_node_point(aes(filter = leaf, colour = class)) +
geom_node_text(aes(filter = members > 25, label = members))
p
ggraph(den_to_igraph(hr), 'treemap') +
geom_node_treemap(aes(filter = leaf, fill = species), colour = NA) +
geom_node_treemap(aes(size = members), colour = 'grey20') +
scale_size(range = c(0.5, 4), trans = 'sqrt', guide = 'none')
Relationship between nodes outside of network structure
Currently only support for hierarchical edge bundles
ggraph(flareGraph, 'dendrogram', circular = TRUE) +
geom_edge_bundle(aes(alpha = ..index..), data = gCon(importFrom, importTo)) +
geom_node_point(aes(filter = leaf, colour = class)) +
coord_fixed()
highGr <- graph_from_data_frame(highschool)
V(highGr)$community <- cluster_walktrap(highGr)$membership
V(highGr)$popularity <- degree(highGr, mode = 'in')
p <- ggraph(highGr, 'igraph', alg = 'kk') +
geom_edge_fan(aes(alpha = ..index..)) +
geom_node_point(aes(size = popularity))
p
p + facet_graph(nodes = community, edges = year)