Skip to content

Visualization in igraph 2

Szabolcs Horvát edited this page Feb 9, 2023 · 5 revisions

This page discusses possible improvements to the visualization system that require major breaking changes. These improvements should be considered for igraph 2.

How are layouts specified?

Currently, layouts can be specified in three ways:

  1. A layout graph attribute that stores the name of a layout function.
  2. A layout graph attribute that stores a coordinate matrix.
  3. Separate x, y and possibly z vertex attributes.

The plot function looks for the layout graph attribute first, and if present uses it. If not, it looks for x, y vertex attributes.

Issues with layouts and graph modification

The advantage of the first method (specifying a layout function) is that the graph will maintain a reasonable layout even if it is modified (vertices are added or removed). However, at present, layout functions can only provide vertex coordinates, but not edge routing.

The second method (coordinate matrix) is problematic because any graph modification that changes the number of vertices makes the layout matrix invalid. In comparison, with the third method the layout stays valid during graph modification. Despite this major limitation of the second method, the add_layout_ function adds a layout matrix instead of x and y vertex attributes.

We should consider changing the layout system so that graph modifications are more convenient.

Limitations of layout functions

At the moment, layout functions simply return a coordinate matrix. Therefore, they can only communicate information about vertex placement, not edge routing. There are many graph layouts which generate both vertex coordinates and edge routing. Currently, only one is implemented in igraph, the Sugiyama layout for DAGs, but we expect more, such as hierarchical edge bundling or advanced layouts that minimize edge crossings (see e.g. https://github.com/igraph/igraph/issues/2297)

Because of this limitation, layout_with_sugiyama cannot be used in the usual way with the layout graph attribute or the layout parameter of plot. https://github.com/igraph/rigraph/issues/496

Layout functions should be redesigned so that they can communicate both vertex placement and edge routing.

Limited support for per-component layout

Most graph layouts are designed for connected graphs. The best way to handle disconnected graphs is to layout out each connected component separately, then use a "packing layout" algorithm to merge the component layouts. Mathematica already implements this and provides several "packing layouts" for merging components back together. We can look there for inspiration.

R/igraph is already moving in this direction with the component_wise argument of layout_, with merge_coords(), which implements a single packing method at the moment, and layout_components(). However, it is not yet convenient to work with these, e.g. there is no simple and concise way to specify a graph layout and a packing layout separately, without hard-coding coordinates into the graph.

There should be an easy way to specify a graph layout and a packing layout separately.

Inspiration

The following are worth looking at before designing a new layout system:

  • Mathematica's layout system is free of all of the above-mentioned problems, except that it only has limited support for edge routing.
  • OGDF and the Handbook of Graph Drawing: https://ogdf.uos.de/. Look at these to see what the state of the art layout methods are, and design igraph's layout system to it can accommodate these in the future.
  • GraphViz