Use case: I'm trying to plot an archaeological "Harris Matrix" in R using the excellent ggraph
package. A Harris Matrix is a directed graph of relationships modeling the chronological relationship between stratigraphic contexts.
I can get pretty close using igraph's Sugiyama layout, and geom_edge_elbow for right-angled edges (see reprex below for code):-
BUT: in an orthodox-styled Harris Matrix, edges for the entry and exit of a node lie above or below the node (not behind/or on top of it), depending on whether they are incoming (before) or outgoing (after), in order to separate more clearly the chronological flow being represented. The result should look a bit like this:-
Can this be done using ggraph
? I can't find any options within either geom_edge_elbow or geom_node_label to do so. If not, are there other ways in R to plot such diagrams, ideally with static export and interactive (e.g. Shiny) options?
(NB: Question cross-posted to a ggraph issue on github).
library(tidyverse)
library(igraph)
library(ggraph)
context_entities = data.frame(
name=c("100","101","102","103","104","105")
)
matrix_relationships <- data.frame(
to= c("100","101","102","101","103","103"),
from= c("101","102","103","103","104","105"),
rel= c("before","before","before","before","before","before")
)
#create graph and depth map
harris_matrix_graph <- igraph::graph_from_data_frame(matrix_relationships, directed = T,
vertices=context_entities)
# igraph origin of layout
harris_matrix_graph_layout <- harris_matrix_graph |>
igraph::layout_with_sugiyama()
harris_matrix_graph %>% ggraph::ggraph(layout="sugiyama") +
ggraph::geom_edge_elbow() +
ggraph::geom_node_label(aes(label=name))
Each "annotate" draws a "Z" shaped elbow. Or best said, a ┏┚ shape.
library(igraph)
library(ggraph)
library(ggplot2)
context_entities = data.frame(
name=c("100","101","102","103","104","105")
)
matrix_relationships <- data.frame(
to= c("100","101","102","101","103","103"),
from= c("101","102","103","103","104","105"),
rel= c("before","before","before","before","before","before")
)
#create graph and depth map
harris_matrix_graph <- igraph::graph_from_data_frame(matrix_relationships, directed = T,
vertices=context_entities)
# igraph origin of layout
harris_matrix_graph_layout <- harris_matrix_graph |> layout_with_sugiyama()
edges <- as_edgelist(harris_matrix_graph, names = F)
layout <- harris_matrix_graph_layout$layout
p <- ggraph::ggraph(harris_matrix_graph, layout="sugiyama")
for (i in seq_len(NROW(edges))) {
p <- p + annotate("segment", x = layout[edges[i,1], 1], y = layout[edges[i,1], 2],
xend = layout[edges[i,1], 1], yend = (layout[edges[i,1], 2] + layout[edges[i,2], 2])/2)
p <- p + annotate("segment", x = layout[edges[i,1], 1], y = (layout[edges[i,1], 2] + layout[edges[i,2], 2])/2,
xend = layout[edges[i,2], 1], yend = (layout[edges[i,1], 2] + layout[edges[i,2], 2])/2)
p <- p + annotate("segment", x = layout[edges[i,2], 1], y = (layout[edges[i,1], 2] + layout[edges[i,2], 2])/2,
xend = layout[edges[i,2], 1], yend = layout[edges[i,2], 2])
}
p <- p + ggraph::geom_node_label(aes(label=name))
p
Created on 2024-10-07 with reprex v2.1.1