Skip to content

Commit 81e789d

Browse files
committed
feat: align_layout()
1 parent ad4a3f5 commit 81e789d

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

src/_igraph/igraphmodule.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,38 @@ PyObject* igraphmodule_set_status_handler(PyObject* self, PyObject* o) {
227227
Py_RETURN_NONE;
228228
}
229229

230+
PyObject* igraphmodule_align_layout(PyObject* self, PyObject* args, PyObject* kwds) {
231+
static char* kwlist[] = {"graph", "layout", NULL};
232+
PyObject *graph_o, *layout_o;
233+
PyObject *res;
234+
igraph_t *graph;
235+
igraph_matrix_t layout;
236+
237+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &graph_o, &layout_o)) {
238+
return NULL;
239+
}
240+
241+
if (igraphmodule_PyObject_to_igraph_t(graph_o, &graph)) {
242+
return NULL;
243+
}
244+
245+
if (igraphmodule_PyObject_to_matrix_t(layout_o, &layout, "layout")) {
246+
return NULL;
247+
}
248+
249+
if (igraph_layout_align(graph, &layout)) {
250+
igraphmodule_handle_igraph_error();
251+
igraph_matrix_destroy(&layout);
252+
return NULL;
253+
}
254+
255+
res = igraphmodule_matrix_t_to_PyList(&layout, IGRAPHMODULE_TYPE_FLOAT);
256+
257+
igraph_matrix_destroy(&layout);
258+
259+
return res;
260+
}
261+
230262
PyObject* igraphmodule_convex_hull(PyObject* self, PyObject* args, PyObject* kwds) {
231263
static char* kwlist[] = {"vs", "coords", NULL};
232264
PyObject *vs, *o, *o1 = 0, *o2 = 0, *o1_float, *o2_float, *coords = Py_False;
@@ -790,6 +822,10 @@ static PyMethodDef igraphmodule_methods[] =
790822
METH_VARARGS | METH_KEYWORDS,
791823
"_power_law_fit(data, xmin=-1, force_continuous=False, p_precision=0.01)\n--\n\n"
792824
},
825+
{"_align_layout", (PyCFunction)igraphmodule_align_layout,
826+
METH_VARARGS | METH_KEYWORDS,
827+
"_align_layout(graph, layout)\n--\n\n"
828+
},
793829
{"convex_hull", (PyCFunction)igraphmodule_convex_hull,
794830
METH_VARARGS | METH_KEYWORDS,
795831
"convex_hull(vs, coords=False)\n--\n\n"

src/igraph/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@
227227
from igraph.io.images import _write_graph_to_svg
228228
from igraph.layout import (
229229
Layout,
230+
align_layout,
230231
_layout,
231232
_layout_auto,
232233
_layout_sugiyama,

src/igraph/layout.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
__all__ = (
1818
"Layout",
19+
"align_layout",
1920
"_layout",
2021
"_layout_auto",
2122
"_layout_sugiyama",
@@ -534,6 +535,27 @@ def _layout(graph, layout=None, *args, **kwds):
534535
return layout
535536

536537

538+
def align_layout(graph, layout):
539+
"""Aligns a graph layout with the coordinate axes
540+
541+
This function centers a vertex layout on the coordinate system origin and
542+
rotates the layout to achieve a visually pleasing alignment with the coordinate
543+
axes. Doing this is particularly useful with force-directed layouts such as
544+
L{Graph.layout_fruchterman_reingold}. Layouts in arbitrary dimensional spaces
545+
are supported.
546+
547+
@param graph: the graph that the layout is associated with.
548+
@param layout: the L{Layout} object containing the vertex coordinates
549+
to align.
550+
@return: a new aligned L{Layout} object.
551+
"""
552+
from igraph._igraph import _align_layout
553+
554+
if not isinstance(layout, Layout):
555+
layout = Layout(layout)
556+
557+
return Layout(_align_layout(graph, layout.coords))
558+
537559
def _layout_auto(graph, *args, **kwds):
538560
"""Chooses and runs a suitable layout function based on simple
539561
topological properties of the graph.

0 commit comments

Comments
 (0)