Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ doc/source/api/**

# Cythonized extension .c files
planarity/full/*.c
planarity/classic/*.c
planarity/express/*.c
8 changes: 2 additions & 6 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ include planarity/c/README

recursive-include planarity/c/ *.h

include planarity/classic/cplanarity.pxd
include planarity/classic/planarity.c
include planarity/classic/planarity.pyx
include planarity/express/cplanarity.pxd
include planarity/express/planarity.pyx

include planarity/full/cgraphLib.pxd
include planarity/full/graphLib.pxd
include planarity/full/graph.pxd
include planarity/full/graphLib.c
include planarity/full/graph.c
include planarity/full/g6IterationUtils.c
include planarity/full/graphLib.pyx
include planarity/full/graph.pyx
include planarity/full/g6IterationUtils.pyx
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ In [11]: print(planarity.ascii(edgelist))
```python
In [12]: planarity.draw(edgelist, outfileName='K5-minus-edge.png', vertex_bordercolor='black')
```
![K_5-minus-edge](https://raw.githubusercontent.com/graph-algorithms/planarity/master/examples/classic/output/K5-minus-edge.png
![K_5-minus-edge](https://raw.githubusercontent.com/graph-algorithms/planarity/master/examples/express/output/K5-minus-edge.png
"Matplotlib render of $K_5$-minus-edge")

Note that edge `(a, b)` would correspond to an edge between vertex indexes
Expand Down
Binary file removed examples/classic/output/K5-minus-edge.png
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added examples/express/output/K5-minus-edge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions planarity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .classic.planarity import PGraph
from .classic.planarity_functions import *
from .classic.planarity_networkx import *
from .express.planarity import PGraph
from .express.planarity_functions import *
from .express.planarity_networkx import *

# Surfaced from planarityc/graphLib/lowLevelUtils/apiutils.h
from .full.graphLib import (
Expand Down Expand Up @@ -108,4 +108,4 @@

# NOTE: In the future, we could automatically generate the version number by
# configuring setuptools-scm, but presently this seems simpler.
__version__ = "1.0.0"
__version__ = "1.0.1"
File renamed without changes.
File renamed without changes.
File renamed without changes.
54 changes: 29 additions & 25 deletions planarity/classic/planarity.pyx → planarity/express/planarity.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ from libc.stdlib cimport free
import typing
import warnings

from planarity.classic cimport cplanarity
from planarity.express cimport cplanarity


cdef class PGraph:
"""Wraps a C-layer graph data structure instance and retains node label data from the caller.

Attributes:
theGraph: The C-layer graph data structure instance wrapped by the
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
nodemap (dict[typing.Any, int]): the mapping of original labels to the
internal vertex indexes.
reverse_nodemap (dict[int, typing.Any]): The mapping of internal vertex
indexes to their original labels.
_embedding_workflow_status (int): Indicates the status of the embedding
workflow; the value is not meaningful until after an embedding
workflow method such as one of the following has been called:
* :py:meth:`~planarity.classic.planarity.PGraph.is_planar`
* :py:meth:`~planarity.classic.planarity.PGraph.embed_planar`
* :py:meth:`~planarity.classic.planarity.PGraph.embed_drawplanar`

- :py:meth:`~planarity.express.planarity.PGraph.is_planar`
- :py:meth:`~planarity.express.planarity.PGraph.embed_planar`
- :py:meth:`~planarity.express.planarity.PGraph.embed_drawplanar`

Note that these are called by several of the other member methods.

Expand All @@ -39,7 +40,7 @@ cdef class PGraph:
cdef int _embedding_workflow_status

def __init__(self, graph):
"""Initialize :py:class:`~planarity.classic.planarity.PGraph` from an input graph.
"""Initialize :py:class:`~planarity.express.planarity.PGraph` from an input graph.

Args:
graph (networkx.Graph | dict[typing.Any, collections.abc.Iterable[typing.Any]] | list[list[typing.Any] | tuple[typing.Any, typing.Any]]):
Expand All @@ -48,9 +49,9 @@ cdef class PGraph:

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if an error was encountered by C-layer methods such
as ``gp_New()``, ``gp_EnsureVertexCapacity()``, or
``gp_DynamicAddEdge()``.
Expand Down Expand Up @@ -98,7 +99,7 @@ cdef class PGraph:

n = len(nodes)
# NOTE: This presumes 1-based arrays; however, this can only be changed
# if you add -DUSE_0BASEDARRAYS to the extra_compile_args of the classic
# if you add -DUSE_0BASEDARRAYS to the extra_compile_args of the express
# planarity extension in setup.py.
self.nodemap = dict(zip(nodes, range(1, n+1)))
self.reverse_nodemap = dict(zip(range(1, n+1), nodes))
Expand Down Expand Up @@ -420,10 +421,11 @@ cdef class PGraph:
)
)

# NOTE: The DrawPlanar context data gives geometric positioning;
# a value of -1 indicates an error state, and therefore the
# drawplanar_edge_info should not be included (i.e., the
# final tuple member will be an empty dict)
# NOTE: The DrawPlanar context data gives geometric
# positioning; a value of -1 indicates an error state,
# and therefore the drawplanar_edge_info should not be
# included (i.e., the final tuple member will be an
# empty dict)
if (
edge_position > -1 and
edge_start > -1 and
Expand Down Expand Up @@ -490,12 +492,13 @@ cdef class PGraph:
Matplotlib and then saved to ``outfileName``, if given.

Args:
labels (bool): If ``True``, vertex labels are rendered in the drawing.
Otherwise, vertices are rendered unlabelled in the drawing. If a
label's rendered width would exceed its vertex's own bounding
rectangle, the label is truncated with a trailing ``...`` so it
stays within that rectangle (see Issue #91). The vertex's
geometry itself is never resized to accommodate a label.
labels (bool): If ``True``, vertex labels are rendered in the
drawing. Otherwise, vertices are rendered unlabelled in the
drawing. If a label's rendered width would exceed its vertex's
own bounding rectangle, the label is truncated with a trailing
``...`` so it stays within that rectangle (see Issue #91). The
vertex's geometry itself is never resized to accommodate a
label.
outfileName (:obj:`str`): File to which to output a Matplotlib
rendering of the planar graph. If not given, then the caller can
call :external+matplotlib:py:func:`matplotlib.pyplot.savefig`.
Expand Down Expand Up @@ -621,11 +624,13 @@ cdef class PGraph:
ax = plt.gca()
ax.add_collection(p)

# Sets the aspect ratio of the axes to 'equal', then recomputes
# the geometric limits from the vertex and edge drawings, and
# autoscales the view limits of the plot using these limits.
# Sets the aspect ratio of the axes to 'equal', then recomputes
# the geometric limits from the vertex and edge drawings, removes
# any default margins, and then autoscales the view limits of the plot
# using these limits.
ax.set_aspect('equal', adjustable='box')
ax.relim()
ax.margins(0)
ax.autoscale_view()

#flipping y axis direction
Expand Down Expand Up @@ -715,9 +720,8 @@ cdef class PGraph:

Returns:
A mapping between the integers assigned to the vertices, by
:py:class:`~planarity.classic.planarity.PGraph` initialization,
:py:class:`~planarity.express.planarity.PGraph` initialization,
and their original labels provided to
:py:class:`~planarity.classic.planarity.PGraph` initialization.
:py:class:`~planarity.express.planarity.PGraph` initialization.
"""
return self.reverse_nodemap

Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ def is_planar(graph):
"""Tests whether or not the graph is planar.

Constructs a
:py:class:`~planarity.classic.planarity.PGraph`
and calls its :py:meth:`~planarity.classic.planarity.PGraph.is_planar`
:py:class:`~planarity.express.planarity.PGraph`
and calls its :py:meth:`~planarity.express.planarity.PGraph.is_planar`
method.

Args:
graph: A graph specified in a format that may be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.

Returns:
``True`` if the graph is planar, or ``False`` if not.

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if an error was encountered by C-layer methods such
as ``gp_Embed()``.
RuntimeError: if a prior invocation of this method already failed.
Expand All @@ -47,23 +47,23 @@ def kuratowski_edges(graph):
"""Returns a list of the edges in a minimal non-planar subgraph of the graph.

Constructs a
:py:class:`~planarity.classic.planarity.PGraph`
:py:class:`~planarity.express.planarity.PGraph`
and calls its
:py:meth:`~planarity.classic.planarity.PGraph.kuratowski_edges` method.
:py:meth:`~planarity.express.planarity.PGraph.kuratowski_edges` method.

Args:
graph: A graph specified in a format that may be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.

Returns:
A list of the edges in a minimal non-planar subgraph of the graph,
if it is non-planar, or an empty list if it is planar.

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if an error was encountered by C-layer methods such
as ``gp_Embed()``.
RuntimeError: if a prior invocation of this method already failed.
Expand All @@ -77,22 +77,22 @@ def ascii(graph) -> str:
"""Produces an ASCII string rendition of the graph, if it is planar.

Constructs a
:py:class:`~planarity.classic.planarity.PGraph`
:py:class:`~planarity.express.planarity.PGraph`
and calls its
:py:meth:`~planarity.classic.planarity.PGraph.ascii` method.
:py:meth:`~planarity.express.planarity.PGraph.ascii` method.

Args:
graph: A graph specified in a format that may be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.

Returns:
An ASCII string rendition of a planar graph.

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if an error was encountered by C-layer methods
such as ``gp_Embed()`` or ``gp_DrawPlanar_RenderToString()``.
RuntimeError: if a prior invocation of this method already failed.
Expand All @@ -107,21 +107,21 @@ def draw(graph, labels=True, outfileName=None, **kwargs):
"""Draws the graph with Matplotlib, if it is planar.

Constructs a
:py:class:`~planarity.classic.planarity.PGraph`
:py:class:`~planarity.express.planarity.PGraph`
and calls its
:py:meth:`~planarity.classic.planarity.PGraph.draw` method with the
:py:meth:`~planarity.express.planarity.PGraph.draw` method with the
given ``labels`` and ``outfileName``.

Args:
graph: A graph specified in a format that may be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
labels (bool): If ``True``, vertex labels are rendered in the drawing.
Otherwise, vertices are rendered unlabelled in the drawing.
outfileName (:obj:`str`): File to which to output a Matplotlib
rendering of the planar graph. If not given, then the caller can
call :external+matplotlib:py:func:`matplotlib.pyplot.savefig`.
**kwargs: Optional figure-level parameters forwarded to
:py:meth:`~planarity.classic.planarity.PGraph.draw`. Supported keys
:py:meth:`~planarity.express.planarity.PGraph.draw`. Supported keys
are:

* ``figsize`` and ``dpi``
Expand All @@ -132,15 +132,15 @@ def draw(graph, labels=True, outfileName=None, **kwargs):
* ``edge_linecolor``
* ``transparent``

Please see the :py:meth:`~planarity.classic.planarity.PGraph.draw`
Please see the :py:meth:`~planarity.express.planarity.PGraph.draw`
documentation for more information and for default values.

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
ValueError: if an unsupported keyword argument is given.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
ImportError: if dependencies from Matplotlib fail to be imported.
RuntimeError: if an error was encountered by C-layer methods
such as ``gp_Embed()``.
Expand All @@ -164,24 +164,24 @@ def write(graph, path: str = 'stdout', writeMode: int = WRITE_ADJLIST) -> None:
"""Writes the graph to ``path``.

Constructs a
:py:class:`~planarity.classic.planarity.PGraph`
:py:class:`~planarity.express.planarity.PGraph`
and calls its
:py:meth:`~planarity.classic.planarity.PGraph.write` method with the
:py:meth:`~planarity.express.planarity.PGraph.write` method with the
specified ``path`` and ``writeMode``.

Args:
graph: A graph specified in a format that may be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
path (str): Path to which to write graph. Defaults to ``stdout``
stream.
writeMode (int): Format to write the graph. Defaults to
``WRITE_ADJLIST``.

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the C-layer ``gp_Write()`` failed.
"""
planarity.PGraph(graph).write(path, writeMode)
Expand All @@ -192,24 +192,24 @@ def mapping(graph) -> dict[int, typing.Any]:
"""Returns the map of integer vertex labels to their original labels.

Constructs a
:py:class:`~planarity.classic.planarity.PGraph`
:py:class:`~planarity.express.planarity.PGraph`
and calls its
:py:meth:`~planarity.classic.planarity.PGraph.mapping` method.
:py:meth:`~planarity.express.planarity.PGraph.mapping` method.

Args:
graph: A graph specified in a format that may be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.

Returns:
A mapping between the integers assigned to the vertices, by
:py:class:`~planarity.classic.planarity.PGraph` initialization,
:py:class:`~planarity.express.planarity.PGraph` initialization,
and their original labels provided to
:py:class:`~planarity.classic.planarity.PGraph` initialization.
:py:class:`~planarity.express.planarity.PGraph` initialization.

Raises:
ValueError: if the given graph is already a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
RuntimeError: if the graph couldn't be converted to a
:py:class:`~planarity.classic.planarity.PGraph`.
:py:class:`~planarity.express.planarity.PGraph`.
"""
return planarity.PGraph(graph).mapping()
Loading
Loading