# igraph Reference Manual

For using the igraph C library

# Chapter 18. Generating Layouts for Graph Drawing

## 1. 2D layout generators

Layout generator functions (or at least most of them) try to place the vertices and edges of a graph on a 2D plane or in 3D space in a way which visually pleases the human eye.

They take a graph object and a number of parameters as arguments and return an igraph_matrix_t, in which each row gives the coordinates of a vertex.

### 1.1. `igraph_layout_random` — Places the vertices uniform randomly on a plane.

```int igraph_layout_random(const igraph_t *graph, igraph_matrix_t *res);
```

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed.

Returns:

 Error code. The current implementation always returns with success.

Time complexity: O(|V|), the number of vertices.

### 1.2. `igraph_layout_circle` — Places the vertices uniformly on a circle, in the order of vertex ids.

```int igraph_layout_circle(const igraph_t *graph, igraph_matrix_t *res);
```

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed.

Returns:

 Error code.

Time complexity: O(|V|), the number of vertices.

### 1.3. `igraph_layout_star` — Generate a star-like layout

```int igraph_layout_star(const igraph_t *graph, igraph_matrix_t *res,
igraph_integer_t center, const igraph_vector_t *order);
```

Arguments:

 `graph`: The input graph. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed. `center`: The id of the vertex to put in the center. `order`: A numeric vector giving the order of the vertices (including the center vertex!). If a null pointer, then the vertices are placed in increasing vertex id order.

Returns:

 Error code.

Time complexity: O(|V|), linear in the number of vertices.

 `igraph_layout_circle()` and other layout generators.

### 1.4. `igraph_layout_grid` — Places the vertices on a regular grid on the plane.

```int igraph_layout_grid(const igraph_t *graph, igraph_matrix_t *res, long int width);
```

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed. `width`: The number of vertices in a single row of the grid. When zero or negative, the width of the grid will be the square root of the number of vertices, rounded up if needed.

Returns:

 Error code. The current implementation always returns with success.

Time complexity: O(|V|), the number of vertices.

### 1.5. `igraph_layout_graphopt` — Optimizes vertex layout via the graphopt algorithm.

```int igraph_layout_graphopt(const igraph_t *graph, igraph_matrix_t *res,
igraph_integer_t niter,
igraph_real_t node_charge, igraph_real_t node_mass,
igraph_real_t spring_length,
igraph_real_t spring_constant,
igraph_real_t max_sa_movement,
igraph_bool_t use_seed);
```

This is a port of the graphopt layout algorithm by Michael Schmuhl. graphopt version 0.4.1 was rewritten in C and the support for layers was removed (might be added later) and a code was a bit reorganized to avoid some unnecessary steps is the node charge (see below) is zero.

graphopt uses physical analogies for defining attracting and repelling forces among the vertices and then the physical system is simulated until it reaches an equilibrium. (There is no simulated annealing or anything like that, so a stable fixed point is not guaranteed.)

Arguments:

 `graph`: The input graph. `res`: Pointer to an initialized matrix, the result will be stored here and its initial contents is used the starting point of the simulation if the `use_seed` argument is true. Note that in this case the matrix should have the proper size, otherwise a warning is issued and the supplied values are ignored. If no starting positions are given (or they are invalid) then a random staring position is used. The matrix will be resized if needed. `niter`: Integer constant, the number of iterations to perform. Should be a couple of hundred in general. If you have a large graph then you might want to only do a few iterations and then check the result. If it is not good enough you can feed it in again in the `res` argument. The original graphopt default if 500. `node_charge`: The charge of the vertices, used to calculate electric repulsion. The original graphopt default is 0.001. `node_mass`: The mass of the vertices, used for the spring forces. The original graphopt defaults to 30. `spring_length`: The length of the springs, an integer number. The original graphopt defaults to zero. `spring_constant`: The spring constant, the original graphopt defaults to one. `max_sa_movement`: Real constant, it gives the maximum amount of movement allowed in a single step along a single axis. The original graphopt default is 5. `use_seed`: Logical scalar, whether to use the positions in `res` as a starting configuration. See also `res` above.

Returns:

 Error code.

Time complexity: O(n (|V|^2+|E|) ), n is the number of iterations, |V| is the number of vertices, |E| the number of edges. If `node_charge` is zero then it is only O(n|E|).

### 1.6. `igraph_layout_bipartite` — Simple layout for bipartite graphs

```int igraph_layout_bipartite(const igraph_t *graph,
const igraph_vector_bool_t *types,
igraph_matrix_t *res, igraph_real_t hgap,
igraph_real_t vgap, long int maxiter);
```

The layout is created by first placing the vertices in two rows, according to their types. Then the positions within the rows are optimized to minimize edge crossings, by calling `igraph_layout_sugiyama()`.

Arguments:

 `graph`: The input graph. `types`: A boolean vector containing ones and zeros, the vertex types. Its length must match the number of vertices in the graph. `res`: Pointer to an initialized matrix, the result, the x and y coordinates are stored here. `hgap`: The preferred minimum horizontal gap between vertices in the same layer (i.e. vertices of the same type). `vgap`: The distance between layers. `maxiter`: Maximum number of iterations in the crossing minimization stage. 100 is a reasonable default; if you feel that you have too many edge crossings, increase this.

Returns:

 Error code.

### 1.7. The DrL layout generator

DrL is a sophisticated layout generator developed and implemented by Shawn Martin et al. As of October 2012 the original DrL homepage is unfortunately not available. You can read more about this algorithm in the following technical report: Martin, S., Brown, W.M., Klavans, R., Boyack, K.W., DrL: Distributed Recursive (Graph) Layout. SAND Reports, 2008. 2936: p. 1-10.

Only a subset of the complete DrL functionality is included in igraph, parallel runs and recursive, multi-level layouting is not supported.

The parameters of the layout are stored in an `igraph_layout_drl_options_t` structure, this can be initialized by calling the function `igraph_layout_drl_options_init()`. The fields of this structure can then be adjusted by hand if needed. The layout is calculated by an `igraph_layout_drl()` call.

#### 1.7.1. `igraph_layout_drl_options_t` — Parameters for the DrL layout generator

```typedef struct igraph_layout_drl_options_t {
igraph_real_t    edge_cut;
igraph_integer_t init_iterations;
igraph_real_t    init_temperature;
igraph_real_t    init_attraction;
igraph_real_t    init_damping_mult;
igraph_integer_t liquid_iterations;
igraph_real_t    liquid_temperature;
igraph_real_t    liquid_attraction;
igraph_real_t    liquid_damping_mult;
igraph_integer_t expansion_iterations;
igraph_real_t    expansion_temperature;
igraph_real_t    expansion_attraction;
igraph_real_t    expansion_damping_mult;
igraph_integer_t cooldown_iterations;
igraph_real_t    cooldown_temperature;
igraph_real_t    cooldown_attraction;
igraph_real_t    cooldown_damping_mult;
igraph_integer_t crunch_iterations;
igraph_real_t    crunch_temperature;
igraph_real_t    crunch_attraction;
igraph_real_t    crunch_damping_mult;
igraph_integer_t simmer_iterations;
igraph_real_t    simmer_temperature;
igraph_real_t    simmer_attraction;
igraph_real_t    simmer_damping_mult;
} igraph_layout_drl_options_t;
```

Values:

 `edge_cut`: The edge cutting parameter. Edge cutting is done in the late stages of the algorithm in order to achieve less dense layouts. Edges are cut if there is a lot of stress on them (a large value in the objective function sum). The edge cutting parameter is a value between 0 and 1 with 0 representing no edge cutting and 1 representing maximal edge cutting. The default value is 32/40. `init_iterations`: Number of iterations, initial phase. `init_temperature`: Start temperature, initial phase. `init_attraction`: Attraction, initial phase. `init_damping_mult`: Damping factor, initial phase. `liquid_iterations`: Number of iterations in the liquid phase. `liquid_temperature`: Start temperature in the liquid phase. `liquid_attraction`: Attraction in the liquid phase. `liquid_damping_mult`: Multiplicatie damping factor, liquid phase. `expansion_iterations`: Number of iterations in the expansion phase. `expansion_temperature`: Start temperature in the expansion phase. `expansion_attraction`: Attraction, expansion phase. `expansion_damping_mult`: Damping factor, expansion phase. `cooldown_iterations`: Number of iterations in the cooldown phase. `cooldown_temperature`: Start temperature in the cooldown phase. `cooldown_attraction`: Attraction in the cooldown phase. `cooldown_damping_mult`: Damping fact int the cooldown phase. `crunch_iterations`: Number of iterations in the crunch phase. `crunch_temperature`: Start temperature in the crunch phase. `crunch_attraction`: Attraction in the crunch phase. `crunch_damping_mult`: Damping factor in the crunch phase. `simmer_iterations`: Number of iterations in the simmer phase. `simmer_temperature`: Start temperature in te simmer phase. `simmer_attraction`: Attraction in the simmer phase. `simmer_damping_mult`: Multiplicative damping factor in the simmer phase.

#### 1.7.2. `igraph_layout_drl_default_t` — Predefined parameter templates for the DrL layout generator

```typedef enum { IGRAPH_LAYOUT_DRL_DEFAULT=0,
IGRAPH_LAYOUT_DRL_COARSEN,
IGRAPH_LAYOUT_DRL_COARSEST,
IGRAPH_LAYOUT_DRL_REFINE,
IGRAPH_LAYOUT_DRL_FINAL } igraph_layout_drl_default_t;
```

These constants can be used to initialize a set of DrL parameters. These can then be modified according to the user's needs.

Values:

 `IGRAPH_LAYOUT_DRL_DEFAULT`: The deafult parameters. `IGRAPH_LAYOUT_DRL_COARSEN`: Slightly modified parameters to get a coarser layout. `IGRAPH_LAYOUT_DRL_COARSEST`: An even coarser layout. `IGRAPH_LAYOUT_DRL_REFINE`: Refine an already calculated layout. `IGRAPH_LAYOUT_DRL_FINAL`: Finalize an already refined layout.

#### 1.7.3. `igraph_layout_drl_options_init` — Initialize parameters for the DrL layout generator

```int igraph_layout_drl_options_init(igraph_layout_drl_options_t *options,
igraph_layout_drl_default_t templ);
```

This function can be used to initialize the struct holding the parameters for the DrL layout generator. There are a number of predefined templates available, it is a good idea to start from one of these by modifying some parameters.

Arguments:

 `options`: The struct to initialize. `templ`: The template to use. Currently the following templates are supplied: `IGRAPH_LAYOUT_DRL_DEFAULT`, `IGRAPH_LAYOUT_DRL_COARSEN`, `IGRAPH_LAYOUT_DRL_COARSEST`, `IGRAPH_LAYOUT_DRL_REFINE` and `IGRAPH_LAYOUT_DRL_FINAL`.

Returns:

 Error code.

Time complexity: O(1).

#### 1.7.4. `igraph_layout_drl` — The DrL layout generator

```int igraph_layout_drl(const igraph_t *graph, igraph_matrix_t *res,
igraph_bool_t use_seed,
igraph_layout_drl_options_t *options,
const igraph_vector_t *weights,
const igraph_vector_bool_t *fixed);
```

This function implements the force-directed DrL layout generator. Please see more in the following technical report: Martin, S., Brown, W.M., Klavans, R., Boyack, K.W., DrL: Distributed Recursive (Graph) Layout. SAND Reports, 2008. 2936: p. 1-10.

Arguments:

 `graph`: The input graph. `use_seed`: Logical scalar, if true, then the coordinates supplied in the `res` argument are used as starting points. `res`: Pointer to a matrix, the result layout is stored here. It will be resized as needed. `options`: The parameters to pass to the layout generator. `weights`: Edge weights, pointer to a vector. If this is a null pointer then every edge will have the same weight. `fixed`: Pointer to a logical vector, or a null pointer. This can be used to fix the position of some vertices. Vertices for which it is true will not be moved, but stay at the coordinates given in the `res` matrix. This argument is ignored if it is a null pointer or if use_seed is false.

Returns:

 Error code.

Time complexity: ???.

#### 1.7.5. `igraph_layout_drl_3d` — The DrL layout generator, 3d version.

```int igraph_layout_drl_3d(const igraph_t *graph, igraph_matrix_t *res,
igraph_bool_t use_seed,
igraph_layout_drl_options_t *options,
const igraph_vector_t *weights,
const igraph_vector_bool_t *fixed);
```

This function implements the force-directed DrL layout generator. Please see more in the technical report: Martin, S., Brown, W.M., Klavans, R., Boyack, K.W., DrL: Distributed Recursive (Graph) Layout. SAND Reports, 2008. 2936: p. 1-10.

This function uses a modified DrL generator that does the layout in three dimensions.

Arguments:

 `graph`: The input graph. `use_seed`: Logical scalar, if true, then the coordinates supplied in the `res` argument are used as starting points. `res`: Pointer to a matrix, the result layout is stored here. It will be resized as needed. `options`: The parameters to pass to the layout generator. `weights`: Edge weights, pointer to a vector. If this is a null pointer then every edge will have the same weight. `fixed`: Pointer to a logical vector, or a null pointer. This can be used to fix the position of some vertices. Vertices for which it is true will not be moved, but stay at the coordinates given in the `res` matrix. This argument is ignored if it is a null pointer or if use_seed is false.

Returns:

 Error code.

Time complexity: ???.

 `igraph_layout_drl()` for the standard 2d version.

### 1.8. `igraph_layout_fruchterman_reingold` — Places the vertices on a plane according to the Fruchterman-Reingold algorithm.

```int igraph_layout_fruchterman_reingold(const igraph_t *graph, igraph_matrix_t *res,
igraph_integer_t niter, igraph_real_t maxdelta,
igraph_real_t area, igraph_real_t coolexp,
const igraph_vector_t *weight,
const igraph_vector_t *minx,
const igraph_vector_t *maxx,
const igraph_vector_t *miny,
const igraph_vector_t *maxy);
```

This is a force-directed layout, see Fruchterman, T.M.J. and Reingold, E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and Experience, 21/11, 1129--1164, 1991. This function was ported from the SNA R package.

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed. `niter`: The number of iterations to do. A reasonable default value is 500. `maxdelta`: The maximum distance to move a vertex in an iteration. A reasonable default value is the number of vertices. `area`: The area parameter of the algorithm. A reasonable default is the square of the number of vertices. `coolexp`: The cooling exponent of the simulated annealing. A reasonable default is 1.5. `repulserad`: Determines the radius at which vertex-vertex repulsion cancels out attraction of adjacent vertices. A reasonable default is `area` times the number of vertices. `use_seed`: Logical, if true the supplied values in the `res` argument are used as an initial layout, if false a random initial layout is used. `weight`: Pointer to a vector containing edge weights, the attraction along the edges will be multiplied by these. It will be ignored if it is a null-pointer. `minx`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “x” coordinate for every vertex. `maxx`: Same as `minx`, but the maximum “x” coordinates. `miny`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “y” coordinate for every vertex. `maxy`: Same as `miny`, but the maximum “y” coordinates.

Returns:

 Error code.

Time complexity: O(|V|^2) in each iteration, |V| is the number of vertices in the graph.

### 1.9. `igraph_layout_kamada_kawai` — Places the vertices on a plane according the Kamada-Kawai algorithm.

```int igraph_layout_kamada_kawai(const igraph_t *graph, igraph_matrix_t *res,
igraph_integer_t niter, igraph_real_t sigma,
igraph_real_t initemp, igraph_real_t coolexp,
igraph_real_t kkconst, igraph_bool_t use_seed,
const igraph_vector_t *minx,
const igraph_vector_t *maxx,
const igraph_vector_t *miny,
const igraph_vector_t *maxy);
```

This is a force directed layout, see Kamada, T. and Kawai, S.: An Algorithm for Drawing General Undirected Graphs. Information Processing Letters, 31/1, 7--15, 1989. This function was ported from the SNA R package.

Arguments:

 `graph`: A graph object. `res`: Pointer to an initialized matrix object. This will contain the result (x-positions in column zero and y-positions in column one) and will be resized if needed. `niter`: The number of iterations to perform. A reasonable default value is 1000. `sigma`: Sets the base standard deviation of position change proposals. A reasonable default value is the number of vertices / 4. `initemp`: Sets the initial temperature for the annealing. A reasonable default value is 10. `coolexp`: The cooling exponent of the annealing. A reasonable default value is 0.99. `kkconst`: The Kamada-Kawai vertex attraction constant. Typical value: (number of vertices)^2 `use_seed`: Boolean, whether to use the values supplied in the `res` argument as the initial configuration. If zero then a random initial configuration is used. `minx`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “x” coordinate for every vertex. `maxx`: Same as `minx`, but the maximum “x” coordinates. `miny`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “y” coordinate for every vertex. `maxy`: Same as `miny`, but the maximum “y” coordinates.

Returns:

 Error code.

Time complexity: O(|V|^2) for each iteration, |V| is the number of vertices in the graph.

### 1.10. `igraph_layout_mds` — Place the vertices on a plane using multidimensional scaling.

```int igraph_layout_mds(const igraph_t* graph, igraph_matrix_t *res,
const igraph_matrix_t *dist, long int dim,
igraph_arpack_options_t *options);
```

This layout requires a distance matrix, where the intersection of row i and column j specifies the desired distance between vertex i and vertex j. The algorithm will try to place the vertices in a space having a given number of dimensions in a way that approximates the distance relations prescribed in the distance matrix. igraph uses the classical multidimensional scaling by Torgerson; for more details, see Cox & Cox: Multidimensional Scaling (1994), Chapman and Hall, London.

If the input graph is disconnected, igraph will decompose it first into its subgraphs, lay out the subgraphs one by one using the appropriate submatrices of the distance matrix, and then merge the layouts using `igraph_layout_merge_dla`. Since `igraph_layout_merge_dla` works for 2D layouts only, you cannot run the MDS layout on disconnected graphs for more than two dimensions.

Arguments:

 `graph`: A graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized if needed. `dist`: The distance matrix. It must be symmetric and this function does not check whether the matrix is indeed symmetric. Results are unspecified if you pass a non-symmetric matrix here. You can set this parameter to null; in this case, the shortest path lengths between vertices will be used as distances. `dim`: The number of dimensions in the embedding space. For 2D layouts, supply 2 here. `options`: This argument is currently ignored, it was used for ARPACK, but LAPACK is used now for calculating the eigenvectors.

Returns:

 Error code.

Time complexity: usually around O(|V|^2 dim).

### 1.11. `igraph_layout_grid_fruchterman_reingold` — Force based layout generator for large graphs.

```int igraph_layout_grid_fruchterman_reingold(const igraph_t *graph,
igraph_matrix_t *res,
igraph_integer_t niter, igraph_real_t maxdelta,
igraph_real_t area, igraph_real_t coolexp,
igraph_real_t cellsize,
igraph_bool_t use_seed,
const igraph_vector_t *weight);
```

This algorithm is the same as the Fruchterman-Reingold layout generator, but it partitions the 2d space to a grid and and vertex repulsion is calculated only for vertices nearby.

Arguments:

 `graph`: The graph object. `res`: The result, the coordinates in a matrix. The parameter should point to an initialized matrix object and will be resized. `niter`: The number of iterations to do. A reasonable default value is 500. `maxdelta`: The maximum distance to move a vertex in an iteration. A reasonable default value is the number of vertices. `area`: The area parameter of the algorithm. A reasonable default is the square of the number of vertices. `coolexp`: The cooling exponent of the simulated annealing. A reasonable default is 1.5. `repulserad`: Determines the radius at which vertex-vertex repulsion cancels out attraction of adjacent vertices. A reasonable default is `area` times the number of vertices. `cellsize`: The size of the grid cells. A reasonable default is the fourth root of `area` (or the square root of the number of vertices if `area` is also left at its default value) `use_seed`: Logical, if true, the coordinates passed in `res` (should have the appropriate size) will be used for the first iteration. `weight`: Pointer to a vector containing edge weights, the attraction along the edges will be multiplied by these. It will be ignored if it is a null-pointer.

Returns:

 Error code.

Time complexity: ideally (constant number of vertices in each cell) O(niter*(|V|+|E|)), in the worst case O(niter*(|V|^2+|E|)).

### 1.12. `igraph_layout_lgl` — Force based layout algorithm for large graphs.

```int igraph_layout_lgl(const igraph_t *graph, igraph_matrix_t *res,
igraph_integer_t maxit, igraph_real_t maxdelta,
igraph_real_t area, igraph_real_t coolexp,
igraph_integer_t proot);
```

This is a layout generator similar to the Large Graph Layout algorithm and program (http://lgl.sourceforge.net/). But unlike LGL, this version uses a Fruchterman-Reingold style simulated annealing algorithm for placing the vertices. The speedup is achieved by placing the vertices on a grid and calculating the repulsion only for vertices which are closer to each other than a limit.

Arguments:

 `graph`: The (initialized) graph object to place. `res`: Pointer to an initialized matrix object to hold the result. It will be resized if needed. `maxit`: The maximum number of cooling iterations to perform for each layout step. A reasonable default is 150. `maxdelta`: The maximum length of the move allowed for a vertex in a single iteration. A reasonable default is the number of vertices. `area`: This parameter gives the area of the square on which the vertices will be placed. A reasonable default value is the number of vertices squared. `coolexp`: The cooling exponent. A reasonable default value is 1.5. `repulserad`: Determines the radius at which vertex-vertex repulsion cancels out attraction of adjacent vertices. A reasonable default value is `area` times the number of vertices. `cellsize`: The size of the grid cells, one side of the square. A reasonable default value is the fourth root of `area` (or the square root of the number of vertices if `area` is also left at its default value). `proot`: The root vertex, this is placed first, its neighbors in the first iteration, second neighbors in the second, etc. If negative then a random vertex is chosen.

Returns:

 Error code.

Time complexity: ideally O(dia*maxit*(|V|+|E|)), |V| is the number of vertices, dia is the diameter of the graph, worst case complexity is still O(dia*maxit*(|V|^2+|E|)), this is the case when all vertices happen to be in the same grid cell.

### 1.13. `igraph_layout_reingold_tilford` — Reingold-Tilford layout for tree graphs

```int igraph_layout_reingold_tilford(const igraph_t *graph,
igraph_matrix_t *res,
igraph_neimode_t mode,
const igraph_vector_t *roots,
const igraph_vector_t *rootlevel);
```

Arranges the nodes in a tree where the given node is used as the root. The tree is directed downwards and the parents are centered above its children. For the exact algorithm, see:

Reingold, E and Tilford, J: Tidier drawing of trees. IEEE Trans. Softw. Eng., SE-7(2):223--228, 1981

If the given graph is not a tree, a breadth-first search is executed first to obtain a possible spanning tree.

Arguments:

 `graph`: The graph object. `res`: The result, the coordinates in a matrix. The parameter should point to an initialized matrix object and will be resized. `mode`: Specifies which edges to consider when building the tree. If it is `IGRAPH_OUT` then only the outgoing, if it is `IGRAPH_IN` then only the incoming edges of a parent are considered. If it is `IGRAPH_ALL` then all edges are used (this was the behavior in igraph 0.5 and before). This parameter also influences how the root vertices are calculated, if they are not given. See the `roots` parameter. `roots`: The index of the root vertex or root vertices. If this is a non-empty vector then the supplied vertex ids are used as the roots of the trees (or a single tree if the graph is connected). If it is a null pointer of a pointer to an empty vector, then the root vertices are automatically calculated based on topological sorting, performed with the opposite mode than the `mode` argument. After the vertices have been sorted, one is selected from each component. `rootlevel`: This argument can be useful when drawing forests which are not trees (i.e. they are unconnected and have tree components). It specifies the level of the root vertices for every tree in the forest. It is only considered if not a null pointer and the `roots` argument is also given (and it is not a null pointer of an empty vector).

Returns:

 Error code.

Example 18.1.  File `examples/simple/igraph_layout_reingold_tilford.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard st, Cambridge MA, 02139 USA

This program is free software; you can redistribute it and/or modify
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>
#include <math.h>

int main() {

igraph_t g;
FILE *f;
igraph_matrix_t coords;
/* long int i, n; */

f=fopen("igraph_layout_reingold_tilford.in", "r");
igraph_matrix_init(&coords, 0, 0);
igraph_layout_reingold_tilford(&g, &coords, IGRAPH_IN, 0, 0);

/*n=igraph_vcount(&g);
for (i=0; i<n; i++) {
printf("%6.3f %6.3f\n", MATRIX(coords, i, 0), MATRIX(coords, i, 1));
}*/

igraph_matrix_destroy(&coords);
igraph_destroy(&g);
return 0;
}
```

### 1.14. `igraph_layout_reingold_tilford_circular` — Circular Reingold-Tilford layout for trees

```int igraph_layout_reingold_tilford_circular(const igraph_t *graph,
igraph_matrix_t *res,
igraph_neimode_t mode,
const igraph_vector_t *roots,
const igraph_vector_t *rootlevel);
```

This layout is almost the same as `igraph_layout_reingold_tilford()`, but the tree is drawn in a circular way, with the root vertex in the center.

Arguments:

 `graph`: The graph object. `res`: The result, the coordinates in a matrix. The parameter should point to an initialized matrix object and will be resized. `mode`: Specifies which edges to consider when building the tree. If it is `IGRAPH_OUT` then only the outgoing, if it is `IGRAPH_IN` then only the incoming edges of a parent are considered. If it is `IGRAPH_ALL` then all edges are used (this was the behavior in igraph 0.5 and before). This parameter also influences how the root vertices are calculated, if they are not given. See the `roots` parameter. `roots`: The index of the root vertex or root vertices. If this is a non-empty vector then the supplied vertex ids are used as the roots of the trees (or a single tree if the graph is connected). If it is a null pointer of a pointer to an empty vector, then the root vertices are automatically calculated based on topological sorting, performed with the opposite mode than the `mode` argument. After the vertices have been sorted, one is selected from each component. `rootlevel`: This argument can be useful when drawing forests which are not trees (i.e. they are unconnected and have tree components). It specifies the level of the root vertices for every tree in the forest. It is only considered if not a null pointer and the `roots` argument is also given (and it is not a null pointer of an empty vector). Note that if you supply a null pointer here and the graph has multiple components, all of the root vertices will be mapped to the origin of the coordinate system, which does not really make sense.

Returns:

 Error code.

### 1.15. `igraph_layout_sugiyama` — Sugiyama layout algorithm for layered directed acyclic graphs.

```int igraph_layout_sugiyama(const igraph_t *graph, igraph_matrix_t *res,
igraph_t *extd_graph, igraph_vector_t *extd_to_orig_eids,
const igraph_vector_t* layers, igraph_real_t hgap, igraph_real_t vgap,
long int maxiter, const igraph_vector_t *weights);
```

This layout algorithm is designed for directed acyclic graphs where each vertex is assigned to a layer. Layers are indexed from zero, and vertices of the same layer will be placed on the same horizontal line. The X coordinates of vertices within each layer are decided by the heuristic proposed by Sugiyama et al to minimize edge crossings.

You can also try to lay out undirected graphs, graphs containing cycles, or graphs without an a priori layered assignment with this algorithm. igraph will try to eliminate cycles and assign vertices to layers, but there is no guarantee on the quality of the layout in such cases.

The Sugiyama layout may introduce "bends" on the edges in order to obtain a visually more pleasing layout. This is achieved by adding dummy nodes to edges spanning more than one layer. The resulting layout assigns coordinates not only to the nodes of the original graph but also to the dummy nodes. The layout algorithm will also return the extended graph with the dummy nodes. An edge in the original graph may either be mapped to a single edge in the extended graph or a path that starts and ends in the original source and target vertex and passes through multiple dummy vertices. In such cases, the user may also request the mapping of the edges of the extended graph back to the edges of the original graph.

For more details, see K. Sugiyama, S. Tagawa and M. Toda, "Methods for Visual Understanding of Hierarchical Systems". IEEE Transactions on Systems, Man and Cybernetics 11(2):109-125, 1981.

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed. The first |V| rows of the layout will contain the coordinates of the original graph, the remaining rows contain the positions of the dummy nodes. Therefore, you can use the result both with `graph` or with `extended_graph`. `extended_graph`: Pointer to an uninitialized graph object or `NULL`. The extended graph with the added dummy nodes will be returned here. In this graph, each edge points downwards to lower layers, spans exactly one layer and the first |V| vertices coincide with the vertices of the original graph. `extd_to_orig_eids`: Pointer to a vector or `NULL`. If not `NULL`, the mapping from the edge IDs of the extended graph back to the edge IDs of the original graph will be stored here. `layers`: The layer index for each vertex or `NULL` if the layers should be determined automatically by igraph. `hgap`: The preferred minimum horizontal gap between vertices in the same layer. `vgap`: The distance between layers. `maxiter`: Maximum number of iterations in the crossing minimization stage. 100 is a reasonable default; if you feel that you have too many edge crossings, increase this. `weights`: Weights of the edges. These are used only if the graph contains cycles; igraph will tend to reverse edges with smaller weights when breaking the cycles.

## 2. 3D layout generators

### 2.1. `igraph_layout_random_3d` — Random layout in 3D

```int igraph_layout_random_3d(const igraph_t *graph, igraph_matrix_t *res);
```

Arguments:

 `graph`: The graph to place. `res`: Pointer to an initialized matrix object. It will be resized to hold the result.

Returns:

 Error code. The current implementation always returns with success.

Time complexity: O(|V|), the number of vertices.

### 2.2. `igraph_layout_sphere` — Places vertices (more or less) uniformly on a sphere.

```int igraph_layout_sphere(const igraph_t *graph, igraph_matrix_t *res);
```

The algorithm was described in the following paper: Distributing many points on a sphere by E.B. Saff and A.B.J. Kuijlaars, Mathematical Intelligencer 19.1 (1997) 5--11.

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed.

Returns:

 Error code. The current implementation always returns with success.

Time complexity: O(|V|), the number of vertices in the graph.

### 2.3. `igraph_layout_grid_3d` — Places the vertices on a regular grid in the 3D space.

```int igraph_layout_grid_3d(const igraph_t *graph, igraph_matrix_t *res,
long int width, long int height);
```

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed. `width`: The number of vertices in a single row of the grid. When zero or negative, the width is determined automatically. `height`: The number of vertices in a single column of the grid. When zero or negative, the height is determined automatically.

Returns:

 Error code. The current implementation always returns with success.

Time complexity: O(|V|), the number of vertices.

### 2.4. `igraph_layout_fruchterman_reingold_3d` — 3D Fruchterman-Reingold algorithm.

```int igraph_layout_fruchterman_reingold_3d(const igraph_t *graph,
igraph_matrix_t *res,
igraph_integer_t niter, igraph_real_t maxdelta,
igraph_real_t volume, igraph_real_t coolexp,
igraph_bool_t use_seed,
const igraph_vector_t *weight,
const igraph_vector_t *minx,
const igraph_vector_t *maxx,
const igraph_vector_t *miny,
const igraph_vector_t *maxy,
const igraph_vector_t *minz,
const igraph_vector_t *maxz);
```

This is the 3D version of the force based Fruchterman-Reingold layout (see `igraph_layout_fruchterman_reingold` for the 2D version

This function was ported from the SNA R package.

Arguments:

 `graph`: Pointer to an initialized graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized as needed. `niter`: The number of iterations to do. A reasonable default value is 500. `maxdelta`: The maximum distance to move a vertex in an iteration. A reasonable default value is the number of vertices. `volume`: The volume parameter of the algorithm. A reasonable default is the number of vertices^3. `coolexp`: The cooling exponent of the simulated annealing. A reasonable default is 1.5. `repulserad`: Determines the radius at which vertex-vertex repulsion cancels out attraction of adjacent vertices. A reasonable default is `volume` times the number of vertices. `use_seed`: Logical, if true the supplied values in the `res` argument are used as an initial layout, if false a random initial layout is used. `weight`: Pointer to a vector containing edge weights, the attraction along the edges will be multiplied by these. It will be ignored if it is a null-pointer. `minx`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “x” coordinate for every vertex. `maxx`: Same as `minx`, but the maximum “x” coordinates. `miny`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “y” coordinate for every vertex. `maxy`: Same as `miny`, but the maximum “y” coordinates. `minz`: Pointer to a vector, or a `NULL` pointer. If not a `NULL` pointer then the vector gives the minimum “z” coordinate for every vertex. `maxz`: Same as `minz`, but the maximum “z” coordinates.

Returns:

 Error code.

Time complexity: O(|V|^2) in each iteration, |V| is the number of vertices in the graph.

### 2.5. `igraph_layout_kamada_kawai_3d` — 3D version of the force based Kamada-Kawai layout.

```int igraph_layout_kamada_kawai_3d(const igraph_t *graph, igraph_matrix_t *res,
igraph_integer_t niter, igraph_real_t sigma,
igraph_real_t initemp, igraph_real_t coolexp,
igraph_real_t kkconst, igraph_bool_t use_seed,
igraph_bool_t fixz,
const igraph_vector_t *minx,
const igraph_vector_t *maxx,
const igraph_vector_t *miny,
const igraph_vector_t *maxy,
const igraph_vector_t *minz,
const igraph_vector_t *maxz);
```

The pair of the `igraph_layout_kamada_kawai` 2D layout generator

This function was ported from the SNA R package.

Arguments:

 `graph`: A graph object. `res`: Pointer to an initialized matrix object. This will contain the result and will be resized if needed. `niter`: The number of iterations to perform. A reasonable default value is 1000. `sigma`: Sets the base standard deviation of position change proposals. A reasonable default value is the number of vertices / 4. `initemp`: Sets the initial temperature for the annealing. A reasonable default value is 10. `coolexp`: The cooling exponent of the annealing. A reasonable default value is 0.99. `kkconst`: The Kamada-Kawai vertex attraction constant. Typical value: (number of vertices)^2 `use_seed`: Boolean, whether to use the values cupplied in the `res` argument as the initial configuration. If zero then a random initial configuration is used. `fixz`: Logical, whether to fix the third coordinate of the input matrix.

Returns:

 Error code.

Time complexity: O(|V|^2) for each iteration, |V| is the number of vertices in the graph.

## 3. Merging layouts

### 3.1. `igraph_layout_merge_dla` — Merge multiple layouts by using a DLA algorithm

```int igraph_layout_merge_dla(igraph_vector_ptr_t *thegraphs,
igraph_vector_ptr_t *coords,
igraph_matrix_t *res);
```

First each layout is covered by a circle. Then the layout of the largest graph is placed at the origin. Then the other layouts are placed by the DLA algorithm, larger ones first and smaller ones last.

Arguments:

 `thegraphs`: Pointer vector containing the graph object of which the layouts will be merged. `coords`: Pointer vector containing matrix objects with the 2d layouts of the graphs in `thegraphs`. `res`: Pointer to an initialized matrix object, the result will be stored here. It will be resized if needed.

Returns:

 Error code.

Added in version 0.2. This function is experimental.

Time complexity: TODO.