4

I want to plot a graph using facets, where the edges vary between panels. The panels are automatically ordered alphabetically (as is customary in ggplot). A simple example:

library(igraph)
library(ggraph)

g <- make_empty_graph() + 
  vertices(1:2) +
  edges(1:2, 2:1, g = c('b', 'a'))

ggraph(g, 'kk') + 
  geom_edge_link(arrow = grid::arrow()) + 
  geom_node_label(aes(label = name)) +
  facet_edges(~g)

enter image description here

This is great, the node positions are presevered, but the edges differ depending on g.

However, I want to choose the order that facets appear. So in this case, first b then a, just like I ordered them while creating the graph above.

In ggplot one would change the order of the factor g. However, creating a layout does not show g:

create_layout(g, 'kk')
           x             y name ggraph.orig_index circular ggraph.index
1 -0.9021575 -1.410825e+00    1                 1    FALSE            1
2 -1.0000000  1.224606e-16    2                 2    FALSE            2

Changing the edge attributes into a factor manually, does change the ordering, but the labels are coerced to numeric:

g2 <- make_empty_graph() + 
  vertices(1:2) +
  edges(1:2, 2:1, g = factor(c('b', 'a'), levels = c('b', 'a')))

ggraph(g2, 'kk') + 
  geom_edge_link(arrow = grid::arrow()) + 
  geom_node_label(aes(label = name)) +
  facet_edges(~g)

enter image description here

How can I give custom ordering for the facets?

Axeman
  • 32,068
  • 8
  • 81
  • 94

2 Answers2

4

One possible solution is to coerce to factor first (as the second plot in the question), then use a custom labeller that simply parrots back the actual factor labels:

my_lab <- function(labels) {
  list(g = c('b', 'a'))
}

ggraph(g2, 'kk') + 
  geom_edge_link(arrow = grid::arrow()) + 
  geom_node_label(aes(label = name)) +
  facet_edges(~g, labeller = my_lab)

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94
2

ggraph uses the same concept as ggplot2, that is, ordering of categorical data is done by using factors. Therefore you would control the facet order by encoding the ordering as levels in the facet variable.

There is a slight problem though - igraph does not have very good support for factors so factors will often be dropped when assigned to node or edge data. I have submitted a PR to igraph that solves this, but in the meantime I would suggest you use tidygraph which works around this problem. Eventually tidygraph will be used behind everything in ggraph so you might just as well get on board

If you are determined to work directly in igraph and can't wait for the next version you can get factors into igraph by using vertex.attributes() in this manner:

vertex.attributes(graph)$factor_attr <- value

Or equivalently with edge.attributes

ThomasP85
  • 1,624
  • 2
  • 15
  • 26
  • Thanks Thomas! I'm not married to igraph at all, but I am planning to use this in a CRAN release, so I guess tidygraph is a bit too early days for now. I'll keep an eye on future developments and will try that igraph code! – Axeman May 27 '17 at 00:06
  • Tidygraph will be released on CRAN over the summer following the next dplyr release, so depending on your timeframe it might not be an issue – ThomasP85 May 27 '17 at 08:56