From 7d0d6aa7a1580c2fbd24dd0036c73b72ec8c428f Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 27 May 2021 11:01:41 -0400 Subject: [PATCH 01/21] Prepare 0.9.0 release This commit starts the preparation for the 0.9.0 release. It moves all the release notes for the release into a separate folder (to distinguish them from notes for future releases) and also reworks the content of the release notes and updates the documentation for the release. This commit should be the last one merged before releasing 0.9.0 to ensure we've moved and updated all the release notes before the release. Partially implements #328 --- docs/source/index.rst | 40 ++++++++++++++++++- docs/source/networkx.rst | 2 + docs/source/release_notes.rst | 7 +++- ...tree-graph-generator-1f6ff6ba3809b901.yaml | 23 +++++++++++ .../add-copy-method-f2abb1222b323dab.yaml | 0 .../add-core_number-b1d3b2fb7ebd276f.yaml | 0 ...-edge-indices-method-c1868ab1dab61b18.yaml | 0 .../add-num-methods-08ac0963b9961f5e.yaml | 0 .../add-nx-converter-1feffc8d5aa13365.yaml | 0 ...ndom-geometric-graph-ef131e3955c6b178.yaml | 14 +++++++ .../add-random-layout-c1c2751be971e5d0.yaml | 0 ...ransitivity-function-c32d2bbbf3857c40.yaml | 2 +- .../bump-msrv-d581a8cbeff8915b.yaml | 0 .../complement-361c90c7dda69df8.yaml | 0 .../custom-path-returns-e1d5fc1e02809179.yaml | 0 .../dijkstra-all-pairs-ecdc3d9a5a267350.yaml | 0 .../expand-isomorphism-cfb646cfef66fa25.yaml | 14 +++++++ .../extend-generators-07a5d34d5e637a6a.yaml | 23 +++++++++++ .../find-successors-by-d3589b1b1d0b1633.yaml | 8 ++++ .../fixed-mutability-0ab3030db0d77239.yaml | 0 .../floyd-warshall-fix-d8ec2131dfaeab82.yaml | 0 ...rphic-matching-order-be0cfa8b796cd55c.yaml | 11 +++++ ...inimum-spanning-tree-4afa29b3c0dbd2fb.yaml | 11 +++++ .../mpl-draw-f2a3224671907eaf.yaml | 0 ...-directed-generators-dc7bbb53480d5d0a.yaml | 0 .../0.9.0/prepare-0.9-dab64f0197fc6233.yaml | 11 +++++ .../0.9.0/spring-layout-c21a31f21bc113a0.yaml | 7 ++++ .../write_edge_list-5f3de403770a811e.yaml | 0 ...tree-graph-generator-1f6ff6ba3809b901.yaml | 4 -- ...ndom-geometric-graph-ef131e3955c6b178.yaml | 5 --- .../expand-isomorphism-cfb646cfef66fa25.yaml | 9 ----- .../extend-generators-07a5d34d5e637a6a.yaml | 5 --- .../find-successors-by-d3589b1b1d0b1633.yaml | 6 --- ...rphic-matching-order-be0cfa8b796cd55c.yaml | 7 ---- ...inimum-spanning-tree-4afa29b3c0dbd2fb.yaml | 6 --- .../notes/spring-layout-c21a31f21bc113a0.yaml | 6 --- retworkx/__init__.py | 28 +++++++++++-- src/digraph.rs | 32 ++++++++++++--- src/graph.rs | 27 +++++++++---- 39 files changed, 241 insertions(+), 67 deletions(-) create mode 100644 releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml rename releasenotes/notes/{ => 0.9.0}/add-copy-method-f2abb1222b323dab.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/add-core_number-b1d3b2fb7ebd276f.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/add-edge-indices-method-c1868ab1dab61b18.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/add-num-methods-08ac0963b9961f5e.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/add-nx-converter-1feffc8d5aa13365.yaml (100%) create mode 100644 releasenotes/notes/0.9.0/add-random-geometric-graph-ef131e3955c6b178.yaml rename releasenotes/notes/{ => 0.9.0}/add-random-layout-c1c2751be971e5d0.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/add-transitivity-function-c32d2bbbf3857c40.yaml (66%) rename releasenotes/notes/{ => 0.9.0}/bump-msrv-d581a8cbeff8915b.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/complement-361c90c7dda69df8.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/custom-path-returns-e1d5fc1e02809179.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/dijkstra-all-pairs-ecdc3d9a5a267350.yaml (100%) create mode 100644 releasenotes/notes/0.9.0/expand-isomorphism-cfb646cfef66fa25.yaml create mode 100644 releasenotes/notes/0.9.0/extend-generators-07a5d34d5e637a6a.yaml create mode 100644 releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml rename releasenotes/notes/{ => 0.9.0}/fixed-mutability-0ab3030db0d77239.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/floyd-warshall-fix-d8ec2131dfaeab82.yaml (100%) create mode 100644 releasenotes/notes/0.9.0/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml create mode 100644 releasenotes/notes/0.9.0/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml rename releasenotes/notes/{ => 0.9.0}/mpl-draw-f2a3224671907eaf.yaml (100%) rename releasenotes/notes/{ => 0.9.0}/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml (100%) create mode 100644 releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml create mode 100644 releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml rename releasenotes/notes/{ => 0.9.0}/write_edge_list-5f3de403770a811e.yaml (100%) delete mode 100644 releasenotes/notes/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml delete mode 100644 releasenotes/notes/add-random-geometric-graph-ef131e3955c6b178.yaml delete mode 100644 releasenotes/notes/expand-isomorphism-cfb646cfef66fa25.yaml delete mode 100644 releasenotes/notes/extend-generators-07a5d34d5e637a6a.yaml delete mode 100644 releasenotes/notes/find-successors-by-d3589b1b1d0b1633.yaml delete mode 100644 releasenotes/notes/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml delete mode 100644 releasenotes/notes/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml delete mode 100644 releasenotes/notes/spring-layout-c21a31f21bc113a0.yaml diff --git a/docs/source/index.rst b/docs/source/index.rst index 599c210533..ab425e391a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,12 +2,48 @@ retworkx Documentation ###################### +retworkx is a Python package for working with graphs and complex networks. It +enables the creation, interaction with, and study of graphs and networks. + +It provides: + + * Data structures for creating graphs including directed graphs and multigraphs + * A library of standard graph algorithms + * Generators for various types of graphs including random graphs + * Visualization functions for graphs + +It is licensed under the +`Apache 2.0 `__ license and the +source code is hosted on Github at: + +https://github.com/Qiskit/retworkx + +retworkx is written in the +`Rust programming language `__ to leverage Rust's +inherent performance and safety. While this provides numerous advantages +including significantly improved performance it does mean that the library +needs to be compiled when being installed from source (as opposed to a pure +Python library which can just be installed). retworkx supports and publishes +pre-compiled binaries for Linux on x86, x86_64, aarch64, s390x, and ppc64le, +MacOS on x86_64, and arm64, and Windows 32bit and 64bit systems. However if +you're running outside of these platforms to install retworkx you will need a +rust compiler installed. + +retworkx was originally created to be a high performance replacement for the +Qiskit project's internal usage of the `NetworkX `__ +library (which is where the name comes from Rust + NetworkX = retworkx) but is +not a drop-in replacement for NetworkX (see :ref:`networkx` for more details). +However, since it was originally created it has grown to be an independent +high performance general purpose graph library that can be used for any +application that needs to interact with graphs or complex networks. + + Contents: .. toctree:: - :maxdepth: 3 + :maxdepth: 2 - README + Overview and Installation Retworkx API Visualization Release Notes diff --git a/docs/source/networkx.rst b/docs/source/networkx.rst index 683e17bfe2..1ed3d17636 100644 --- a/docs/source/networkx.rst +++ b/docs/source/networkx.rst @@ -1,3 +1,5 @@ +.. _networkx: + ########################### retworkx for networkx users ########################### diff --git a/docs/source/release_notes.rst b/docs/source/release_notes.rst index adfd39f069..ae79c0f5e3 100644 --- a/docs/source/release_notes.rst +++ b/docs/source/release_notes.rst @@ -1,4 +1,8 @@ -.. release-notes:: Release Notes +************* +Release Notes +************* + +.. release-notes:: 0.7.1 ===== @@ -97,6 +101,7 @@ Fixes source. This has been fixed so building from sdist will always use known working versions that we use for testing in CI. + 0.6.0 ===== diff --git a/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml b/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml new file mode 100644 index 0000000000..093a71b8f0 --- /dev/null +++ b/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml @@ -0,0 +1,23 @@ +--- +features: + - | + Added a new generator functions, + :func:`retworkx.generators.binomial_tree_graph` and + :func:`retworkx.generators.directed_binomial_tree_graph`, for constructing + a binomial tree graph. For example: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.binomial_tree_graph(4) + mpl_draw(graph) + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.directed_binomial_tree_graph(4) + mpl_draw(graph) diff --git a/releasenotes/notes/add-copy-method-f2abb1222b323dab.yaml b/releasenotes/notes/0.9.0/add-copy-method-f2abb1222b323dab.yaml similarity index 100% rename from releasenotes/notes/add-copy-method-f2abb1222b323dab.yaml rename to releasenotes/notes/0.9.0/add-copy-method-f2abb1222b323dab.yaml diff --git a/releasenotes/notes/add-core_number-b1d3b2fb7ebd276f.yaml b/releasenotes/notes/0.9.0/add-core_number-b1d3b2fb7ebd276f.yaml similarity index 100% rename from releasenotes/notes/add-core_number-b1d3b2fb7ebd276f.yaml rename to releasenotes/notes/0.9.0/add-core_number-b1d3b2fb7ebd276f.yaml diff --git a/releasenotes/notes/add-edge-indices-method-c1868ab1dab61b18.yaml b/releasenotes/notes/0.9.0/add-edge-indices-method-c1868ab1dab61b18.yaml similarity index 100% rename from releasenotes/notes/add-edge-indices-method-c1868ab1dab61b18.yaml rename to releasenotes/notes/0.9.0/add-edge-indices-method-c1868ab1dab61b18.yaml diff --git a/releasenotes/notes/add-num-methods-08ac0963b9961f5e.yaml b/releasenotes/notes/0.9.0/add-num-methods-08ac0963b9961f5e.yaml similarity index 100% rename from releasenotes/notes/add-num-methods-08ac0963b9961f5e.yaml rename to releasenotes/notes/0.9.0/add-num-methods-08ac0963b9961f5e.yaml diff --git a/releasenotes/notes/add-nx-converter-1feffc8d5aa13365.yaml b/releasenotes/notes/0.9.0/add-nx-converter-1feffc8d5aa13365.yaml similarity index 100% rename from releasenotes/notes/add-nx-converter-1feffc8d5aa13365.yaml rename to releasenotes/notes/0.9.0/add-nx-converter-1feffc8d5aa13365.yaml diff --git a/releasenotes/notes/0.9.0/add-random-geometric-graph-ef131e3955c6b178.yaml b/releasenotes/notes/0.9.0/add-random-geometric-graph-ef131e3955c6b178.yaml new file mode 100644 index 0000000000..3f47cccecf --- /dev/null +++ b/releasenotes/notes/0.9.0/add-random-geometric-graph-ef131e3955c6b178.yaml @@ -0,0 +1,14 @@ +--- +features: + - | + Added new function :func:`~retworkx.random_geometric_graph` which can be + used to generate random geometric graphs. For example: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + + graph = retworkx.random_geometric_graph(8, .95, 5) + mpl_draw(graph) diff --git a/releasenotes/notes/add-random-layout-c1c2751be971e5d0.yaml b/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml similarity index 100% rename from releasenotes/notes/add-random-layout-c1c2751be971e5d0.yaml rename to releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml diff --git a/releasenotes/notes/add-transitivity-function-c32d2bbbf3857c40.yaml b/releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml similarity index 66% rename from releasenotes/notes/add-transitivity-function-c32d2bbbf3857c40.yaml rename to releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml index 5c7054f727..e1a9f82ac6 100644 --- a/releasenotes/notes/add-transitivity-function-c32d2bbbf3857c40.yaml +++ b/releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml @@ -1,6 +1,6 @@ --- features: - | - A new function, :func:`~retworkx.transitivity` was added to + Added new function, :func:`~retworkx.transitivity` was added to calculate the transitivity coefficient of a :class:`~retworkx.PyGraph` and a :class:`~retworkx.PyDiGraph`. diff --git a/releasenotes/notes/bump-msrv-d581a8cbeff8915b.yaml b/releasenotes/notes/0.9.0/bump-msrv-d581a8cbeff8915b.yaml similarity index 100% rename from releasenotes/notes/bump-msrv-d581a8cbeff8915b.yaml rename to releasenotes/notes/0.9.0/bump-msrv-d581a8cbeff8915b.yaml diff --git a/releasenotes/notes/complement-361c90c7dda69df8.yaml b/releasenotes/notes/0.9.0/complement-361c90c7dda69df8.yaml similarity index 100% rename from releasenotes/notes/complement-361c90c7dda69df8.yaml rename to releasenotes/notes/0.9.0/complement-361c90c7dda69df8.yaml diff --git a/releasenotes/notes/custom-path-returns-e1d5fc1e02809179.yaml b/releasenotes/notes/0.9.0/custom-path-returns-e1d5fc1e02809179.yaml similarity index 100% rename from releasenotes/notes/custom-path-returns-e1d5fc1e02809179.yaml rename to releasenotes/notes/0.9.0/custom-path-returns-e1d5fc1e02809179.yaml diff --git a/releasenotes/notes/dijkstra-all-pairs-ecdc3d9a5a267350.yaml b/releasenotes/notes/0.9.0/dijkstra-all-pairs-ecdc3d9a5a267350.yaml similarity index 100% rename from releasenotes/notes/dijkstra-all-pairs-ecdc3d9a5a267350.yaml rename to releasenotes/notes/0.9.0/dijkstra-all-pairs-ecdc3d9a5a267350.yaml diff --git a/releasenotes/notes/0.9.0/expand-isomorphism-cfb646cfef66fa25.yaml b/releasenotes/notes/0.9.0/expand-isomorphism-cfb646cfef66fa25.yaml new file mode 100644 index 0000000000..7d64828363 --- /dev/null +++ b/releasenotes/notes/0.9.0/expand-isomorphism-cfb646cfef66fa25.yaml @@ -0,0 +1,14 @@ +--- +features: + - | + The :func:`~retworkx.is_isomorphic` function has been expanded so it can + now also take in a :class:`~retworkx.PyGraph` in addition to the + the :class:`~retworkx.PyDiGraph` already supported. + - | + The :func:`~retworkx.is_isomorphic` function now has two new optional + kwargs ``node_matcher`` and ``edge_matcher`` which can be used to specify + functions to use for comparing node and edge data payloads. + - | + The :func:`~retworkx.is_isomorphic_node_match` function has been expanded + so it can take in a :class:`~retworkx.PyGraph` in addition to the + :class:`~retworkx.PyDiGraph` it already supported. diff --git a/releasenotes/notes/0.9.0/extend-generators-07a5d34d5e637a6a.yaml b/releasenotes/notes/0.9.0/extend-generators-07a5d34d5e637a6a.yaml new file mode 100644 index 0000000000..b36bf6bb40 --- /dev/null +++ b/releasenotes/notes/0.9.0/extend-generators-07a5d34d5e637a6a.yaml @@ -0,0 +1,23 @@ +--- +features: + - | + Added new generator functions, + :func:`retworkx.generators.directed_hexagonal_lattice_graph` and + :func:`retworkx.generators.hexagonal_lattice_graph`, for constructing a + hexagonal lattice graph. For example: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.directed_hexagonal_lattice_graph(3, 3) + mpl_draw(graph) + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.hexagonal_lattice_graph(3, 3) + mpl_draw(graph) diff --git a/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml b/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml new file mode 100644 index 0000000000..acfb3c1734 --- /dev/null +++ b/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Added two new methods, :meth:`~retworkx.PyDiGraph.find_successors_by_edge` + and :meth:`~retworkx.PyDiGraph.find_predecessors_by_edge`, were added to + :class:`~retworkx.PyDiGraph`. These methods efficiently retrieve the + neighbors in the graph which are connected to a node with edges matching a + filter function. diff --git a/releasenotes/notes/fixed-mutability-0ab3030db0d77239.yaml b/releasenotes/notes/0.9.0/fixed-mutability-0ab3030db0d77239.yaml similarity index 100% rename from releasenotes/notes/fixed-mutability-0ab3030db0d77239.yaml rename to releasenotes/notes/0.9.0/fixed-mutability-0ab3030db0d77239.yaml diff --git a/releasenotes/notes/floyd-warshall-fix-d8ec2131dfaeab82.yaml b/releasenotes/notes/0.9.0/floyd-warshall-fix-d8ec2131dfaeab82.yaml similarity index 100% rename from releasenotes/notes/floyd-warshall-fix-d8ec2131dfaeab82.yaml rename to releasenotes/notes/0.9.0/floyd-warshall-fix-d8ec2131dfaeab82.yaml diff --git a/releasenotes/notes/0.9.0/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml b/releasenotes/notes/0.9.0/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml new file mode 100644 index 0000000000..94b5cc97bf --- /dev/null +++ b/releasenotes/notes/0.9.0/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + The :func:`~retworkx.is_isomorphic` and + :func:`~retworkx.is_isomorphic_node_match` functions have a new kwarg, + ``id_order`` which is used to adjust the node matching order used. + If you set ``id_order=False`` then the matching order used is the heuristic + matching order proposed in the + `VF2++ paper `__. If you + want to retain use the order based on node ids, you can set + ``id_order=True`` which is the default behavior. diff --git a/releasenotes/notes/0.9.0/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml b/releasenotes/notes/0.9.0/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml new file mode 100644 index 0000000000..25b48e6dc6 --- /dev/null +++ b/releasenotes/notes/0.9.0/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Added new function, :func:`~retworkx.minimum_spanning_tree`, to calculate the + minimum spanning tree of a :class:`~retworkx.PyGraph` object and return the + MST as a new :class:`~retworkx.PyGraph` object. + - | + Added a new function, :func:`~retworkx.minimum_spanning_edges`, to calculate + the minimum spanning tree of a :class:`~retworkx.PyGraph` object and return + the :class:`~retworkx.WeightedEdgeList` for the weighted edge list of the + MST of a graph. diff --git a/releasenotes/notes/mpl-draw-f2a3224671907eaf.yaml b/releasenotes/notes/0.9.0/mpl-draw-f2a3224671907eaf.yaml similarity index 100% rename from releasenotes/notes/mpl-draw-f2a3224671907eaf.yaml rename to releasenotes/notes/0.9.0/mpl-draw-f2a3224671907eaf.yaml diff --git a/releasenotes/notes/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml b/releasenotes/notes/0.9.0/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml similarity index 100% rename from releasenotes/notes/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml rename to releasenotes/notes/0.9.0/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml diff --git a/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml b/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml new file mode 100644 index 0000000000..9c87010402 --- /dev/null +++ b/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml @@ -0,0 +1,11 @@ +--- +prelude: | + This release is a new feature release that includes a plethora of new + features and bug fixes. The highlights of this release are the introduction + of the :mod:`retwork.visualization` module, which includes a + `matplotlib `__ based drawer + (:func:`~retworkx.visualization.mpl_draw`), and layout functions such + as :func:`~retworkx.spring_layout` for generating a layout in + visualization. Additionally, the generator functions in + :mod:`retworkx.generators` have been expanded to include new graph + generators, and new algorithm functions have been added. diff --git a/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml b/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml new file mode 100644 index 0000000000..a53d23cbb0 --- /dev/null +++ b/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Added a new function, :func:`~retworkx.spring_layout` to generate layouts + for :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` + using the `Fruchterman-Reingold force-directed algorithm + `__. diff --git a/releasenotes/notes/write_edge_list-5f3de403770a811e.yaml b/releasenotes/notes/0.9.0/write_edge_list-5f3de403770a811e.yaml similarity index 100% rename from releasenotes/notes/write_edge_list-5f3de403770a811e.yaml rename to releasenotes/notes/0.9.0/write_edge_list-5f3de403770a811e.yaml diff --git a/releasenotes/notes/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml b/releasenotes/notes/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml deleted file mode 100644 index 23bef73d62..0000000000 --- a/releasenotes/notes/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -features: - - | - Added a new generator for constructing a binomial tree graph (:func:`retworkx.generators.binomial_tree_graph`). diff --git a/releasenotes/notes/add-random-geometric-graph-ef131e3955c6b178.yaml b/releasenotes/notes/add-random-geometric-graph-ef131e3955c6b178.yaml deleted file mode 100644 index 4faf085ebe..0000000000 --- a/releasenotes/notes/add-random-geometric-graph-ef131e3955c6b178.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -features: - - | - A new function :func:`~retworkx.random_geometric_graph` was added - to generate random geometric graphs. diff --git a/releasenotes/notes/expand-isomorphism-cfb646cfef66fa25.yaml b/releasenotes/notes/expand-isomorphism-cfb646cfef66fa25.yaml deleted file mode 100644 index c8153a3aef..0000000000 --- a/releasenotes/notes/expand-isomorphism-cfb646cfef66fa25.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -features: - - | - :func:`~retworkx.is_isomorphic` can take in a :class:`~retworkx.PyGraph` - or :class:`~retworkx.PyDiGraph`. You can optionally specify two functions - to compare node and edge data. - - | - :func:`~retworkx.is_isomorphic_node_match` can take in a :class:`~retworkx.PyGraph` - or :class:`~retworkx.PyDiGraph`. diff --git a/releasenotes/notes/extend-generators-07a5d34d5e637a6a.yaml b/releasenotes/notes/extend-generators-07a5d34d5e637a6a.yaml deleted file mode 100644 index f42cc8b899..0000000000 --- a/releasenotes/notes/extend-generators-07a5d34d5e637a6a.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -features: - - | - Added new generators for constructing a hexagonal lattice graph (:func:`retworkx.generators.hexagonal_lattice_graph`) - and directed hexagonal lattice graph (:func:`retworkx.generators.directed_hexagonal_lattice_graph`). diff --git a/releasenotes/notes/find-successors-by-d3589b1b1d0b1633.yaml b/releasenotes/notes/find-successors-by-d3589b1b1d0b1633.yaml deleted file mode 100644 index 3f1a527b36..0000000000 --- a/releasenotes/notes/find-successors-by-d3589b1b1d0b1633.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -features: - - | - Two new functions were added to :class:`~retworkx.PyDiGraph`: :meth:`~retworkx.PyDiGraph.find_successors_by_edge` - and :meth:`~retworkx.PyDiGraph.find_predecessors_by_edge` to efficiently retrieve the neighbors in the graph - who are connected to a node with edges matching a filter function. diff --git a/releasenotes/notes/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml b/releasenotes/notes/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml deleted file mode 100644 index 9d3716579d..0000000000 --- a/releasenotes/notes/is-isomorphic-matching-order-be0cfa8b796cd55c.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -features: - - | - :func:`~retworkx.is_isomorphic` and :func:`~retworkx.is_isomorphic_node_match` - match the nodes in order specified by a heuristic matching order proposed - in VF2++ paper, if `id_order=False`. If you want to use the order based on - node ids, you should set `id_order=True`. diff --git a/releasenotes/notes/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml b/releasenotes/notes/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml deleted file mode 100644 index da32509eeb..0000000000 --- a/releasenotes/notes/minimum-spanning-tree-4afa29b3c0dbd2fb.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -features: - - | - Two new functions were added: :func:`~retworkx.minimum_spanning_tree` to calculate the - MST of a :class:`~retworkx.PyGraph`, and :func:`~retworkx.minimum_spanning_edges` to - retrieve the :class:`~retworkx.WeightedEdgeList` of the MST of a graph. diff --git a/releasenotes/notes/spring-layout-c21a31f21bc113a0.yaml b/releasenotes/notes/spring-layout-c21a31f21bc113a0.yaml deleted file mode 100644 index aa48261fb2..0000000000 --- a/releasenotes/notes/spring-layout-c21a31f21bc113a0.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -features: - - | - Add a new function, `~retworkx.spring_layout` to generate layouts for - :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` - using Fruchterman-Reingold force-directed algorithm. diff --git a/retworkx/__init__.py b/retworkx/__init__.py index f48c152835..506be6bbce 100644 --- a/retworkx/__init__.py +++ b/retworkx/__init__.py @@ -26,9 +26,11 @@ class PyDAG(PyDiGraph): The PyDAG class is used to create a directed graph. It can be a multigraph (have multiple edges between nodes). Each node and edge - (although rarely used for edges) is indexed by an integer id. Additionally, - each node and edge contains an arbitrary Python object as a weight/data - payload. + (although rarely used for edges) is indexed by an integer id. These ids + are stable for the lifetime of the graph object and on node or edge + deletions you can have holes in the list of indices for the graph. + Additionally, each node and edge contains an arbitrary Python object as a + weight/data payload. You can use the index for access to the data payload as in the following example: @@ -82,6 +84,26 @@ class PyDAG(PyDiGraph): penalty that grows as the graph does. If you're adding a node and edge at the same time, leveraging :meth:`PyDAG.add_child` or :meth:`PyDAG.add_parent` will avoid this overhead. + + By default a ``PyDAG`` is a multigraph (meaning there can be parallel + edges between nodes) however this can be disabled by setting the + ``multigraph`` kwarg to ``False`` when calling the ``PyDAG`` constructor. + For example:: + + import retworkx + dag = retworkx.PyDAG(multigraph=False) + + This can only be set at ``PyDiGraph`` initialization and not adjusted after + creation. When :attr:`~retworkx.PyDiGraph.multigraph` is set to ``False`` + if a method call is made that would add a parallel edge it will instead + update the existing edge's weight/data payload. + + :param bool check_cycle: When this is set to ``True`` the created + ``PyDAG`` has runtime cycle detection enabled. + :param bool multgraph: When this is set to ``False`` the created + ``PyDAG`` object will not be a multigraph. When ``False`` if a method + call is made that would add parallel edges the the weight/weight from + that method call will be used to update the existing edge in place. """ pass diff --git a/src/digraph.rs b/src/digraph.rs index a155f28adf..a3d048eab8 100644 --- a/src/digraph.rs +++ b/src/digraph.rs @@ -56,12 +56,14 @@ use super::{ /// A class for creating directed graphs /// -/// The PyDiGraph class is used to create a directed graph. It can be a +/// The ``PyDiGraph`` class is used to create a directed graph. It can be a /// multigraph (have multiple edges between nodes). Each node and edge -/// (although rarely used for edges) is indexed by an integer id. Additionally -/// each node and edge contains an arbitrary Python object as a weight/data -/// payload. You can use the index for access to the data payload as in the -/// following example: +/// (although rarely used for edges) is indexed by an integer id. These ids +/// are stable for the lifetime of the graph object and on node or edge +/// deletions you can have holes in the list of indices for the graph. +/// Additionally, each node and edge contains an arbitrary Python object as a +/// weight/data payload. You can use the index for access to the data payload +/// as in the following example: /// /// .. jupyter-execute:: /// @@ -112,6 +114,26 @@ use super::{ /// penalty that grows as the graph does. If you're adding a node and edge at /// the same time leveraging :meth:`PyDiGraph.add_child` or /// :meth:`PyDiGraph.add_parent` will avoid this overhead. +/// +/// By default a ``PyDiGraph`` is a multigraph (meaning there can be parallel +/// edges between nodes) however this can be disabled by setting the +/// ``multigraph`` kwarg to ``False`` when calling the ``PyDiGraph`` +/// constructor. For example:: +/// +/// import retworkx +/// graph = retworkx.PyDiGraph(multigraph=False) +/// +/// This can only be set at ``PyDiGraph`` initialization and not adjusted after +/// creation. When :attr:`~retworkx.PyDiGraph.multigraph` is set to ``False`` +/// if a method call is made that would add a parallel edge it will instead +/// update the existing edge's weight/data payload. +/// +/// :param bool check_cycle: When this is set to ``True`` the created +/// ``PyDiGraph`` has runtime cycle detection enabled. +/// :param bool multgraph: When this is set to ``False`` the created +/// ``PyDiGraph`` object will not be a multigraph. When ``False`` if a +/// method call is made that would add parallel edges the the weight/weight +/// from that method call will be used to update the existing edge in place. #[pyclass(module = "retworkx", subclass, gc)] #[text_signature = "(/, check_cycle=False, multigraph=True)"] #[derive(Clone)] diff --git a/src/graph.rs b/src/graph.rs index a05e48f835..ce1bdab099 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -51,10 +51,12 @@ use petgraph::visit::{ /// /// The PyGraph class is used to create an undirected graph. It can be a /// multigraph (have multiple edges between nodes). Each node and edge -/// (although rarely used for edges) is indexed by an integer id. Additionally, -/// each node and edge contains an arbitrary Python object as a weight/data -/// payload. You can use the index for access to the data payload as in the -/// following example: +/// (although rarely used for edges) is indexed by an integer id. These ids +/// are stable for the lifetime of the graph object and on node or edge +/// deletions you can have holes in the list of indices for the graph. +/// Additionally, each node and edge contains an arbitrary Python object as a +/// weight/data payload. You can use the index for access to the data payload +/// as in the following example: /// /// .. jupyter-execute:: /// @@ -80,12 +82,23 @@ use petgraph::visit::{ /// print("Node Index: %s" % node_index) /// print(graph[node_index]) /// +/// By default a ``PyGraph`` is a multigraph (meaning there can be parallel +/// edges between nodes) however this can be disabled by setting the +/// ``multigraph`` kwarg to ``False`` when calling the ``PyGraph`` +/// constructor. For example:: +/// +/// import retworkx +/// graph = retworkx.PyGraph(multigraph=False) +/// +/// This can only be set at ``PyGraph`` initialization and not adjusted after +/// creation. When :attr:`~retworkx.PyGraph.multigraph` is set to ``False`` +/// if a method call is made that would add a parallel edge it will instead +/// update the existing edge's weight/data payload. /// /// :param bool multigraph: When this is set to ``False`` the created PyGraph -/// object will not be a multigraph (which is the default behavior). When -/// ``False`` if parallel edges are added the weight/weight from that +/// object will not be a multigraph. When ``False`` if a method call is +/// made that would add parallel edges the the weight/weight from that /// method call will be used to update the existing edge in place. -/// #[pyclass(module = "retworkx", subclass, gc)] #[text_signature = "(/, multigraph=True)"] #[derive(Clone)] From 71564267ccab8860db92be948115a3c8d00d6f84 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 27 May 2021 17:06:39 -0400 Subject: [PATCH 02/21] Move new release notes --- .../{ => 0.9.0}/pydot-drawer-c5df0aa830679748.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) rename releasenotes/notes/{ => 0.9.0}/pydot-drawer-c5df0aa830679748.yaml (70%) diff --git a/releasenotes/notes/pydot-drawer-c5df0aa830679748.yaml b/releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml similarity index 70% rename from releasenotes/notes/pydot-drawer-c5df0aa830679748.yaml rename to releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml index 3ca07d9e4d..8430c9860d 100644 --- a/releasenotes/notes/pydot-drawer-c5df0aa830679748.yaml +++ b/releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml @@ -7,10 +7,13 @@ features: Graphviz is installed locally and adds two new optional dependencies, `pydot `__ which is used to call Graphviz and `Pillow `__ to interact with the generated - image files. This function wraps the :meth:`~retworkx.PyDiGraph.to_dot` - method to generate a `dot `__ - representation of the graph and will call Graphviz to generate a - visualization of the graph. For example: + image files. The optional dependencies can be installed either with + ``pip install pydot pillow` or when install retworkx with + ``pip install 'retworkx[pydot]'``. This function wraps the + :meth:`~retworkx.PyDiGraph.to_dot` method to generate a + `dot `__ representation of the + graph and will call Graphviz to generate a visualization of the graph. For + example: .. jupyter-execute:: From fda2868a7ccb6af1a1d273cf0e3d4040a1fe561b Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 27 May 2021 17:16:48 -0400 Subject: [PATCH 03/21] Add readme section on optional dependencies --- README.md | 17 +++++++++++++++++ setup.py | 7 +++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9b17f85f96..bb5462bcc2 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,23 @@ pip install retworkx will build retworkx for your local system from the source package and install it just as it would if there was a prebuilt binary available. +### Optional dependencies + +If you're planning to use the `retworkx.visualization` module you will need to +install optional dependencies to use the functions. The matplotlib drawer +required that the [matplotlib](https://matplotlib.org/) library is installed. +This can be installed with `pip install matplotlib` or when you're installing +retworkx with `pip install 'retworkx[mpl]'`. If you're going to use the graphviz +based drawer first you will need to install graphviz, instructions for this can +be found here: https://graphviz.org/download/#executable-packages. Then you +will need to install the [pydot](https://pypi.org/project/pydot/) and +[pillow](https://python-pillow.org/) Python libraries. This can be done either +with `pip install pydot pillow` or when installing retworkx with +`pip install 'retworkx[pydot]'`. + +If you would like to install all the optional Python dependencies when you +install retworkx you can use `pip install 'retworkx[all]'` to do this. + ## Building from source The first step for building retworkx from source is to clone it locally diff --git a/setup.py b/setup.py index 13f007592e..b7e4083933 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,8 @@ def readme(): with open('README.md') as f: return f.read() +mpl_extras = ['matplotlib>=3.0'] +graphviz_extras = ['pydot>=1.4', 'pillow>=5.4'] setup( name="retworkx", @@ -53,7 +55,8 @@ def readme(): python_requires=">=3.6", install_requires=['numpy>=1.16.0'], extras_require={ - 'mpl': ['matplotlib>=3.0'], - 'graphviz': ['pydot>=1.4', 'pillow>=5.4'], + 'mpl': mpl_extras, + 'graphviz': graphviz_extras, + 'all': mpl_extras + graphviz_extras, } ) From 699f5daa8fd374a573859e4e7a79ffb2d6672474 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 27 May 2021 17:26:42 -0400 Subject: [PATCH 04/21] Fix lint --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index b7e4083933..6ac85993d4 100644 --- a/setup.py +++ b/setup.py @@ -14,9 +14,11 @@ def readme(): with open('README.md') as f: return f.read() + mpl_extras = ['matplotlib>=3.0'] graphviz_extras = ['pydot>=1.4', 'pillow>=5.4'] + setup( name="retworkx", version="0.9.0", From f4ec1e47fef87308fa04909d328fb7808d3a4503 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 27 May 2021 17:48:56 -0400 Subject: [PATCH 05/21] Move new release notes --- .../notes/{ => 0.9.0}/edge-index-map-cf07a035d02481a1.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename releasenotes/notes/{ => 0.9.0}/edge-index-map-cf07a035d02481a1.yaml (98%) diff --git a/releasenotes/notes/edge-index-map-cf07a035d02481a1.yaml b/releasenotes/notes/0.9.0/edge-index-map-cf07a035d02481a1.yaml similarity index 98% rename from releasenotes/notes/edge-index-map-cf07a035d02481a1.yaml rename to releasenotes/notes/0.9.0/edge-index-map-cf07a035d02481a1.yaml index 0462469322..ad0d6a60a6 100644 --- a/releasenotes/notes/edge-index-map-cf07a035d02481a1.yaml +++ b/releasenotes/notes/0.9.0/edge-index-map-cf07a035d02481a1.yaml @@ -11,4 +11,4 @@ features: Added a new custom return type :class:`~retworkx.EdgeIndexMap` which is returned by :meth:`retworkx.PyDiGraph.edge_index_map` and :meth:`retworkx.PyGraph.edge_index_map`. It is equivalent to a read-only - dict/mapping that represent a mapping of edge indices to the edge. + dict/mapping that represent a mapping of edge indices to the edge tuple. From fcdf031c449bada3d005e38bf69b7396327244b3 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 28 May 2021 07:49:37 -0400 Subject: [PATCH 06/21] Update readme based on review comments --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bb5462bcc2..4a8f0366c2 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,14 @@ it just as it would if there was a prebuilt binary available. ### Optional dependencies If you're planning to use the `retworkx.visualization` module you will need to -install optional dependencies to use the functions. The matplotlib drawer -required that the [matplotlib](https://matplotlib.org/) library is installed. -This can be installed with `pip install matplotlib` or when you're installing -retworkx with `pip install 'retworkx[mpl]'`. If you're going to use the graphviz -based drawer first you will need to install graphviz, instructions for this can -be found here: https://graphviz.org/download/#executable-packages. Then you +install optional dependencies to use the functions. The matplotlib based drawer +function `retworkx.visualization.mpl_draw` requires that the +[matplotlib](https://matplotlib.org/) library is installed. This can be +installed with `pip install matplotlib` or when you're installing retworkx with +`pip install 'retworkx[mpl]'`. If you're going to use the graphviz based drawer +function `retworkx.visualization.pydot_drawer` first you will need to install +graphviz, instructions for this can be found here: +https://graphviz.org/download/#executable-packages. Then you will need to install the [pydot](https://pypi.org/project/pydot/) and [pillow](https://python-pillow.org/) Python libraries. This can be done either with `pip install pydot pillow` or when installing retworkx with From 8a6b99d94794e15bb9e1feeaf576ce91863e5a9e Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 28 May 2021 07:55:01 -0400 Subject: [PATCH 07/21] Update index intro based on review comments --- docs/source/index.rst | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index ab425e391a..e47b37cd74 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -25,18 +25,17 @@ including significantly improved performance it does mean that the library needs to be compiled when being installed from source (as opposed to a pure Python library which can just be installed). retworkx supports and publishes pre-compiled binaries for Linux on x86, x86_64, aarch64, s390x, and ppc64le, -MacOS on x86_64, and arm64, and Windows 32bit and 64bit systems. However if -you're running outside of these platforms to install retworkx you will need a -rust compiler installed. +MacOS on x86_64, and arm64, and Windows 32bit and 64bit systems. However, if +you are not running on one of these platforms, you will need a rust compiler +to install retworkx. retworkx was originally created to be a high performance replacement for the Qiskit project's internal usage of the `NetworkX `__ -library (which is where the name comes from Rust + NetworkX = retworkx) but is -not a drop-in replacement for NetworkX (see :ref:`networkx` for more details). -However, since it was originally created it has grown to be an independent -high performance general purpose graph library that can be used for any -application that needs to interact with graphs or complex networks. - +library (which is where the name comes from Rust + NetworkX = retworkx) but it +is not a drop-in replacement for NetworkX (see :ref:`networkx` for more +details). However, since it was originally created it has grown to be an +independent high performance general purpose graph library that can be used for +any application that needs to interact with graphs or complex networks. Contents: From 48d3f457df282fccbc1b4444c155f7a9fbba58f8 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 28 May 2021 07:57:13 -0400 Subject: [PATCH 08/21] Update release prelude to mention pydot_draw --- releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml b/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml index 9c87010402..5e01e7d317 100644 --- a/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml +++ b/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml @@ -4,8 +4,10 @@ prelude: | features and bug fixes. The highlights of this release are the introduction of the :mod:`retwork.visualization` module, which includes a `matplotlib `__ based drawer - (:func:`~retworkx.visualization.mpl_draw`), and layout functions such + (:func:`~retworkx.visualization.mpl_draw`) and a + `graphviz `__ based drawer + (:func:`~retworkx.visualization.pydot_draw`), and layout functions such as :func:`~retworkx.spring_layout` for generating a layout in visualization. Additionally, the generator functions in :mod:`retworkx.generators` have been expanded to include new graph - generators, and new algorithm functions have been added. + generators, and many new algorithm functions have been added. From 078a581aac31f8368e01b2f195b99d5dd1070dc1 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 28 May 2021 14:22:10 -0400 Subject: [PATCH 09/21] Move new release notes --- .../0.9.0/add-subgraph-isomorphism-d22c1b5b015769ec.yaml | 6 ++++++ .../notes/add-subgraph-isomorphism-d22c1b5b015769ec.yaml | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/0.9.0/add-subgraph-isomorphism-d22c1b5b015769ec.yaml delete mode 100644 releasenotes/notes/add-subgraph-isomorphism-d22c1b5b015769ec.yaml diff --git a/releasenotes/notes/0.9.0/add-subgraph-isomorphism-d22c1b5b015769ec.yaml b/releasenotes/notes/0.9.0/add-subgraph-isomorphism-d22c1b5b015769ec.yaml new file mode 100644 index 0000000000..c6969aef1b --- /dev/null +++ b/releasenotes/notes/0.9.0/add-subgraph-isomorphism-d22c1b5b015769ec.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Added a new function, :func:`~retworkx.is_subgraph_isomorphic`, to + determine if two graphs of the same type (either :class:`~retworkx.PyGraph` + or :class:`~retworkx.PyDiGraph`) are induced subgraph isomorphic. diff --git a/releasenotes/notes/add-subgraph-isomorphism-d22c1b5b015769ec.yaml b/releasenotes/notes/add-subgraph-isomorphism-d22c1b5b015769ec.yaml deleted file mode 100644 index 68eae489ce..0000000000 --- a/releasenotes/notes/add-subgraph-isomorphism-d22c1b5b015769ec.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -features: - - | - A new function, :func:`~retworkx.is_subgraph_isomorphic` was added to - determine if two graphs of type :class:`~retworkx.PyGraph` or - :class:`~retworkx.PyDiGraph` are induced subgraph isomorphic. From de14c6e7e4d7fda82333fb689eabc9333d00b9d2 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 29 May 2021 15:09:21 -0400 Subject: [PATCH 10/21] Use mpl_draw in docstrings --- retworkx/visualization/matplotlib.py | 1 - src/digraph.rs | 60 +----- src/generators.rs | 285 +++------------------------ src/graph.rs | 59 +----- 4 files changed, 45 insertions(+), 360 deletions(-) diff --git a/retworkx/visualization/matplotlib.py b/retworkx/visualization/matplotlib.py index 21d2be5cc1..78a3b150a3 100644 --- a/retworkx/visualization/matplotlib.py +++ b/retworkx/visualization/matplotlib.py @@ -295,7 +295,6 @@ def draw_graph(graph, pos=None, arrows=True, with_labels=False, **kwds): valid_label_kwds = { "labels", - "edge_labels", "font_size", "font_color", "font_family", diff --git a/src/digraph.rs b/src/digraph.rs index a3d048eab8..ee211daa62 100644 --- a/src/digraph.rs +++ b/src/digraph.rs @@ -1890,14 +1890,10 @@ impl PyDiGraph { /// /// .. jupyter-execute:: /// - /// import os /// import tempfile /// - /// from PIL import Image - /// import pydot - /// /// import retworkx - /// + /// from retworkx.visualization import mpl_draw /// /// with tempfile.NamedTemporaryFile('wt') as fd: /// path = fd.name @@ -1908,16 +1904,7 @@ impl PyDiGraph { /// fd.write('2 3\n') /// fd.flush() /// graph = retworkx.PyDiGraph.read_edge_list(path) - /// - /// # Draw graph - /// dot = pydot.graph_from_dot_data(graph.to_dot())[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'dag.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// mpl_draw(graph) /// #[staticmethod] #[text_signature = "(path, /, comment=None, deliminator=None)"] @@ -2141,30 +2128,15 @@ impl PyDiGraph { /// /// .. jupyter-execute:: /// - /// import os - /// import tempfile - /// - /// import pydot - /// from PIL import Image - /// /// import retworkx + /// from retworkx.visualization import mpl_draw /// /// # Build first graph and visualize: /// graph = retworkx.PyDiGraph() /// node_a = graph.add_node('A') /// node_b = graph.add_child(node_a, 'B', 'A to B') /// node_c = graph.add_child(node_b, 'C', 'B to C') - /// dot_str = graph.to_dot( - /// lambda node: dict( - /// color='black', fillcolor='lightblue', style='filled')) - /// dot = pydot.graph_from_dot_data(dot_str)[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'graph.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// mpl_draw(graph, with_labels=True, labels=str, edge_labels=str) /// /// Then build a second one: /// @@ -2174,17 +2146,7 @@ impl PyDiGraph { /// other_graph = retworkx.PyDiGraph() /// node_d = other_graph.add_node('D') /// other_graph.add_child(node_d, 'E', 'D to E') - /// dot_str = other_graph.to_dot( - /// lambda node: dict( - /// color='black', fillcolor='lightblue', style='filled')) - /// dot = pydot.graph_from_dot_data(dot_str)[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'other_graph.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// mpl_draw(other_graph, with_labels=True, labels=str, edge_labels=str) /// /// Finally compose the ``other_graph`` onto ``graph`` /// @@ -2192,17 +2154,7 @@ impl PyDiGraph { /// /// node_map = {node_b: (node_d, 'B to D')} /// graph.compose(other_graph, node_map) - /// dot_str = graph.to_dot( - /// lambda node: dict( - /// color='black', fillcolor='lightblue', style='filled')) - /// dot = pydot.graph_from_dot_data(dot_str)[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'combined_graph.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// mpl_draw(graph, with_labels=True, labels=str, edge_labels=str) /// #[text_signature = "(self, other, node_map, /, node_map_func=None, edge_map_func=None)"] pub fn compose( diff --git a/src/generators.rs b/src/generators.rs index 4941a3289c..bfa914161e 100644 --- a/src/generators.rs +++ b/src/generators.rs @@ -54,26 +54,11 @@ where /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_cycle_graph(5) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(bidirectional = "false", multigraph = "true")] #[text_signature = "(/, num_nodes=None, weights=None, bidirectional=False, multigraph=True)"] @@ -153,26 +138,11 @@ pub fn directed_cycle_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.cycle_graph(5) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(/, num_nodes=None, weights=None, multigraph=True)"] @@ -243,26 +213,11 @@ pub fn cycle_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_path_graph(10) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(bidirectional = "false", multigraph = "true")] #[text_signature = "(/, num_nodes=None, weights=None, bidirectional=False, multigraph=True)"] @@ -331,26 +286,11 @@ pub fn directed_path_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.path_graph(10) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(/, num_nodes=None, weights=None, multigraph=True)"] @@ -416,49 +356,19 @@ pub fn path_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_star_graph(10) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_star_graph(10, inward=True) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(inward = "false", bidirectional = "false", multigraph = "true")] #[text_signature = "(/, num_nodes=None, weights=None, inward=False, bidirectional=False, multigraph=True)"] @@ -528,26 +438,11 @@ pub fn directed_star_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.star_graph(10) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(/, num_nodes=None, weights=None, multigraph=True)"] @@ -604,26 +499,11 @@ pub fn star_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.mesh_graph(4) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(/, num_nodes=None, weights=None, multigraph=True)"] @@ -684,26 +564,11 @@ pub fn mesh_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_mesh_graph(4) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = "true")] #[text_signature = "(/, num_nodes=None, weights=None, multigraph=True)"] @@ -774,26 +639,11 @@ pub fn directed_mesh_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.grid_graph(2, 3) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(/, rows=None, cols=None, weights=None, multigraph=True)"] @@ -897,26 +747,11 @@ pub fn grid_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_grid_graph(2, 3) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(bidirectional = "false", multigraph = "true")] #[text_signature = "(/, rows=None, cols=None, weights=None, bidirectional=False, multigraph=True)"] @@ -1025,26 +860,11 @@ pub fn directed_grid_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.binomial_tree_graph(4) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(order, /, weights=None, multigraph=True)"] @@ -1137,26 +957,11 @@ pub fn binomial_tree_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_binomial_tree_graph(4) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(bidirectional = "false", multigraph = "true")] #[text_signature = "(order, /, weights=None, bidirectional=False, multigraph=True)"] @@ -1274,26 +1079,11 @@ pub fn directed_binomial_tree_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.hexagonal_lattice_graph(2, 2) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(multigraph = true)] #[text_signature = "(/, rows=None, cols=None, multigraph=True)"] @@ -1375,26 +1165,11 @@ pub fn hexagonal_lattice_graph( /// /// .. jupyter-execute:: /// -/// import os -/// import tempfile -/// -/// import pydot -/// from PIL import Image -/// /// import retworkx.generators +/// from retworkx.visualization import mpl_draw /// /// graph = retworkx.generators.directed_hexagonal_lattice_graph(2, 3) -/// dot_str = graph.to_dot( -/// lambda node: dict( -/// color='black', fillcolor='lightblue', style='filled')) -/// dot = pydot.graph_from_dot_data(dot_str)[0] -/// -/// with tempfile.TemporaryDirectory() as tmpdirname: -/// tmp_path = os.path.join(tmpdirname, 'dag.png') -/// dot.write_png(tmp_path) -/// image = Image.open(tmp_path) -/// os.remove(tmp_path) -/// image +/// mpl_draw(graph) /// #[pyfunction(bidirectional = "false", multigraph = "true")] #[text_signature = "(/, rows=None, cols=None, bidirectional=False, multigraph=True)"] diff --git a/src/graph.rs b/src/graph.rs index ce1bdab099..fd0016769f 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1141,14 +1141,10 @@ impl PyGraph { /// /// .. jupyter-execute:: /// - /// import os /// import tempfile /// - /// from PIL import Image - /// import pydot - /// /// import retworkx - /// + /// from retworkx.visualization import mpl_draw /// /// with tempfile.NamedTemporaryFile('wt') as fd: /// path = fd.name @@ -1159,16 +1155,7 @@ impl PyGraph { /// fd.write('2 3\n') /// fd.flush() /// graph = retworkx.PyGraph.read_edge_list(path) - /// - /// # Draw graph - /// dot = pydot.graph_from_dot_data(graph.to_dot())[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'dag.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// mpl_draw(graph) /// #[staticmethod] #[text_signature = "(path, /, comment=None, deliminator=None)"] @@ -1396,22 +1383,14 @@ impl PyGraph { /// from PIL import Image /// /// import retworkx + /// from retworkx.visualization import mpl_draw /// /// # Build first graph and visualize: /// graph = retworkx.PyGraph() /// node_a, node_b, node_c = graph.add_nodes_from(['A', 'B', 'C']) - /// graph.add_edges_from_no_data([(node_a, node_b), (node_b, node_c)]) - /// dot_str = graph.to_dot( - /// lambda node: dict( - /// color='black', fillcolor='lightblue', style='filled')) - /// dot = pydot.graph_from_dot_data(dot_str)[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'graph.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// graph.add_edges_from([(node_a, node_b, 'A to B'), + /// (node_b, node_c, 'B to C')]) + /// mpl_draw(graph, with_labels=True, labels=str, edge_labels=str) /// /// Then build a second one: /// @@ -1420,18 +1399,8 @@ impl PyGraph { /// # Build second graph and visualize: /// other_graph = retworkx.PyGraph() /// node_d, node_e = other_graph.add_nodes_from(['D', 'E']) - /// other_graph.add_edge(node_d, node_e, None) - /// dot_str = other_graph.to_dot( - /// lambda node: dict( - /// color='black', fillcolor='lightblue', style='filled')) - /// dot = pydot.graph_from_dot_data(dot_str)[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'other_graph.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// other_graph.add_edge(node_d, node_e, 'D to E') + /// mpl_draw(other_graph, with_labels=True, labels=str, edge_labels=str) /// /// Finally compose the ``other_graph`` onto ``graph`` /// @@ -1439,17 +1408,7 @@ impl PyGraph { /// /// node_map = {node_b: (node_d, 'B to D')} /// graph.compose(other_graph, node_map) - /// dot_str = graph.to_dot( - /// lambda node: dict( - /// color='black', fillcolor='lightblue', style='filled')) - /// dot = pydot.graph_from_dot_data(dot_str)[0] - /// - /// with tempfile.TemporaryDirectory() as tmpdirname: - /// tmp_path = os.path.join(tmpdirname, 'combined_graph.png') - /// dot.write_png(tmp_path) - /// image = Image.open(tmp_path) - /// os.remove(tmp_path) - /// image + /// mpl_draw(graph, with_labels=True, labels=str, edge_labels=str) /// #[text_signature = "(self, other, node_map, /, node_map_func=None, edge_map_func=None)"] pub fn compose( From 809f4ed07afd07475d9825ccfac68a10ab30d731 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 29 May 2021 15:47:07 -0400 Subject: [PATCH 11/21] Add example to graphviz_draw doc --- retworkx/visualization/graphviz.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/retworkx/visualization/graphviz.py b/retworkx/visualization/graphviz.py index 20c4d3ca24..48b00f1209 100644 --- a/retworkx/visualization/graphviz.py +++ b/retworkx/visualization/graphviz.py @@ -84,6 +84,23 @@ def graphviz_draw( ``None`` will be returned as the visualization was written to the path specified in ``filename`` :rtype: PIL.Image + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import graphviz_draw + + def node_attr(node): + if node == 0: + return {'color': 'yellow', 'fillcolor': 'yellow', 'style': 'filled'} + if node % 2: + return {'color': 'blue', 'fillcolor': 'blue', 'style': 'filled'} + else: + return {'color': 'red', 'fillcolor': 'red', 'style': 'filled'} + + graph = retworkx.generators.directed_star_graph(weights=list(range(32))) + graphviz_draw(graph, node_attr_fn=node_attr, method='sfdp') + """ if not HAS_PYDOT: raise ImportError( From ad46ad17eb359f949a73ce9e97f2cd45563e9af5 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sat, 29 May 2021 16:42:55 -0400 Subject: [PATCH 12/21] Update add-transitivity-function-c32d2bbbf3857c40.yaml --- .../0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml b/releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml index e1a9f82ac6..a339c1325a 100644 --- a/releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml +++ b/releasenotes/notes/0.9.0/add-transitivity-function-c32d2bbbf3857c40.yaml @@ -1,6 +1,6 @@ --- features: - | - Added new function, :func:`~retworkx.transitivity` was added to + A new function, :func:`~retworkx.transitivity`, was added to calculate the transitivity coefficient of a :class:`~retworkx.PyGraph` - and a :class:`~retworkx.PyDiGraph`. + or a :class:`~retworkx.PyDiGraph` object. From 6b6f2176bf26d63ef3a1d427e0d921c9017530f4 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 30 May 2021 06:02:57 -0400 Subject: [PATCH 13/21] Apply suggestions from code review Co-authored-by: Ivan Carvalho --- .../add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml | 2 +- .../notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml b/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml index 093a71b8f0..e80d4877f2 100644 --- a/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml +++ b/releasenotes/notes/0.9.0/add-binomial-tree-graph-generator-1f6ff6ba3809b901.yaml @@ -1,7 +1,7 @@ --- features: - | - Added a new generator functions, + Added new generator functions, :func:`retworkx.generators.binomial_tree_graph` and :func:`retworkx.generators.directed_binomial_tree_graph`, for constructing a binomial tree graph. For example: diff --git a/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml b/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml index acfb3c1734..1e32f76563 100644 --- a/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml +++ b/releasenotes/notes/0.9.0/find-successors-by-d3589b1b1d0b1633.yaml @@ -2,7 +2,7 @@ features: - | Added two new methods, :meth:`~retworkx.PyDiGraph.find_successors_by_edge` - and :meth:`~retworkx.PyDiGraph.find_predecessors_by_edge`, were added to + and :meth:`~retworkx.PyDiGraph.find_predecessors_by_edge`, to :class:`~retworkx.PyDiGraph`. These methods efficiently retrieve the neighbors in the graph which are connected to a node with edges matching a filter function. From 37220bf81bded7e97429c85afa1a0457901c20cf Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 30 May 2021 06:39:43 -0400 Subject: [PATCH 14/21] Update prepare-0.9-dab64f0197fc6233.yaml --- releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml b/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml index 5e01e7d317..3f61beba90 100644 --- a/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml +++ b/releasenotes/notes/0.9.0/prepare-0.9-dab64f0197fc6233.yaml @@ -6,7 +6,7 @@ prelude: | `matplotlib `__ based drawer (:func:`~retworkx.visualization.mpl_draw`) and a `graphviz `__ based drawer - (:func:`~retworkx.visualization.pydot_draw`), and layout functions such + (:func:`~retworkx.visualization.graphviz_draw`), and layout functions such as :func:`~retworkx.spring_layout` for generating a layout in visualization. Additionally, the generator functions in :mod:`retworkx.generators` have been expanded to include new graph From 0f7719d2dd60f6a53c079fe92e374e18fcd2daac Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 30 May 2021 06:42:15 -0400 Subject: [PATCH 15/21] Update pydot-drawer-c5df0aa830679748.yaml --- releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml b/releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml index 8430c9860d..22b9538e52 100644 --- a/releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml +++ b/releasenotes/notes/0.9.0/pydot-drawer-c5df0aa830679748.yaml @@ -8,8 +8,8 @@ features: `pydot `__ which is used to call Graphviz and `Pillow `__ to interact with the generated image files. The optional dependencies can be installed either with - ``pip install pydot pillow` or when install retworkx with - ``pip install 'retworkx[pydot]'``. This function wraps the + ``pip install pydot pillow` or when installing retworkx with + ``pip install 'retworkx[graphviz]'``. This function wraps the :meth:`~retworkx.PyDiGraph.to_dot` method to generate a `dot `__ representation of the graph and will call Graphviz to generate a visualization of the graph. For From a3f59e6dcfe83e7cc1738c1250fcc5fac6cda66d Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Sun, 30 May 2021 08:16:47 -0400 Subject: [PATCH 16/21] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a8f0366c2..90e911531d 100644 --- a/README.md +++ b/README.md @@ -61,13 +61,13 @@ function `retworkx.visualization.mpl_draw` requires that the [matplotlib](https://matplotlib.org/) library is installed. This can be installed with `pip install matplotlib` or when you're installing retworkx with `pip install 'retworkx[mpl]'`. If you're going to use the graphviz based drawer -function `retworkx.visualization.pydot_drawer` first you will need to install +function `retworkx.visualization.graphviz_drawer` first you will need to install graphviz, instructions for this can be found here: https://graphviz.org/download/#executable-packages. Then you will need to install the [pydot](https://pypi.org/project/pydot/) and [pillow](https://python-pillow.org/) Python libraries. This can be done either with `pip install pydot pillow` or when installing retworkx with -`pip install 'retworkx[pydot]'`. +`pip install 'retworkx[graphviz]'`. If you would like to install all the optional Python dependencies when you install retworkx you can use `pip install 'retworkx[all]'` to do this. From af35224dde8a88487d6e75d929e32ddf2163b50b Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 31 May 2021 13:54:22 -0400 Subject: [PATCH 17/21] Update multigraph release note --- Cargo.lock | 25 +++++++++---------- ...-directed-generators-dc7bbb53480d5d0a.yaml | 20 ++++++++++----- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9d91f508d..cf73ca0086 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,9 +53,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -66,11 +66,10 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg", "cfg-if 1.0.0", "lazy_static", ] @@ -99,9 +98,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", @@ -210,9 +209,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" [[package]] name = "lock_api" @@ -234,9 +233,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg", ] @@ -376,9 +375,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] diff --git a/releasenotes/notes/0.9.0/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml b/releasenotes/notes/0.9.0/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml index 0d54f310fb..f5c01c82cd 100644 --- a/releasenotes/notes/0.9.0/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml +++ b/releasenotes/notes/0.9.0/multigraph-to-directed-generators-dc7bbb53480d5d0a.yaml @@ -1,8 +1,16 @@ --- -fixes: +features: - | - Add a ``multigraph`` argument for the directed digraph generators: - :func:`retworkx.generators.directed_cycle_graph`, :func:`retworkx.generators.directed_path_graph`, - :func:`retworkx.generators.directed_star_graph`, :func:`retworkx.generators.directed_mesh_graph`, - and :func:`retworkx.generators.directed_grid_graph`. This can be used to set whether the generated - :class:`~retworkx.PyDiGraph` objects are multi graphs or not. By default this is set to ``True``. + A new kwarg, ``multigraph`` was added to the :class:`~retworkx.PyDiGraph` + generator functions: + + * :func:`retworkx.generators.directed_cycle_graph` + * :func:`retworkx.generators.directed_path_graph` + * :func:`retworkx.generators.directed_star_graph` + * :func:`retworkx.generators.directed_mesh_graph` + * :func:`retworkx.generators.directed_grid_graph` + + This can be used to set whether the generated + :class:`~retworkx.PyDiGraph` objects are multi graphs or not (to set + whether parallel edges can be added or not). By default this is set to + ``True``. From b80948b4f138a2e74f3ecb4fa4319b247d083194 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 31 May 2021 14:57:22 -0400 Subject: [PATCH 18/21] Move and update last new release note --- .../simple-layouts-93db8f7f5fa1fe83.yaml | 68 +++++++++++++++++++ .../simple-layouts-93db8f7f5fa1fe83.yaml | 6 -- 2 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/0.9.0/simple-layouts-93db8f7f5fa1fe83.yaml delete mode 100644 releasenotes/notes/simple-layouts-93db8f7f5fa1fe83.yaml diff --git a/releasenotes/notes/0.9.0/simple-layouts-93db8f7f5fa1fe83.yaml b/releasenotes/notes/0.9.0/simple-layouts-93db8f7f5fa1fe83.yaml new file mode 100644 index 0000000000..92727df2b9 --- /dev/null +++ b/releasenotes/notes/0.9.0/simple-layouts-93db8f7f5fa1fe83.yaml @@ -0,0 +1,68 @@ +--- +features: + - | + Four simple layout functions were added: + + * :func:`~retworkx.bipartite_layout` + * :func:`~retworkx.circular_layout` + * :func:`~retworkx.shell_layout` + * :func:`~retworkx.spiral_layout` + + These can be used to adjust the layout used in visualizations, for example: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.path_graph(weights=list(range(24))) + layout = retworkx.bipartite_layout(graph, set(range(12))) + mpl_draw(graph, pos=layout) + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.path_graph(weights=list(range(24))) + layout = retworkx.circular_layout(graph) + mpl_draw(graph, pos=layout) + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.star_graph(25) + layout = retworkx.shell_layout(graph) + mpl_draw(graph, pos=layout) + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.path_graph(weights=list(range(24))) + layout = retworkx.spiral_layout(graph) + mpl_draw(graph, pos=layout) + + Or with the :func:`~retworkx.visualization.graphviz_drawer` function: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import graphviz_draw + + graph = retworkx.generators.path_graph(weights=list(range(24))) + layout = retworkx.spiral_layout(graph) + + def node_attr_fn(node): + point = layout[node] + return { + "shape": "circle", + "pos": '"%s,%s!"' % (point[0], point[1]), + "fillcolor": "yellow", + "style": "filled", + } + + graphviz_draw(graph, node_attr_fn=node_attr_fn, method='fdp') diff --git a/releasenotes/notes/simple-layouts-93db8f7f5fa1fe83.yaml b/releasenotes/notes/simple-layouts-93db8f7f5fa1fe83.yaml deleted file mode 100644 index f27c174dcd..0000000000 --- a/releasenotes/notes/simple-layouts-93db8f7f5fa1fe83.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -features: - - | - Four simple layouts were added: :func:`~retworkx.bipartite_layout`, - :func:`~retworkx.circular_layout`, :func:`~retworkx.shell_layout`, - and :func:`~retworkx.spiral_layout`. From 8a2ba01fef861c0a45a7e1a052f949467423bd15 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 31 May 2021 18:13:20 -0400 Subject: [PATCH 19/21] Add examples to spring layout release note --- .../0.9.0/spring-layout-c21a31f21bc113a0.yaml | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml b/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml index a53d23cbb0..095160dbc1 100644 --- a/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml +++ b/releasenotes/notes/0.9.0/spring-layout-c21a31f21bc113a0.yaml @@ -4,4 +4,42 @@ features: Added a new function, :func:`~retworkx.spring_layout` to generate layouts for :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` using the `Fruchterman-Reingold force-directed algorithm - `__. + `__. This + layout method is used by default for the + :func:`~retworkx.visualization.mpl_drawer` visualization function. You + can also explicitly use it when calling + :func:`~retworkx.visualization.mpl_drawer` and + :func:`~retworkx.visualization.graphviz_drawer`. For example: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.random_geometric_graph(15, 1.42) + layout = retworkx.spring_layout(graph, adaptive_cooling=False) + mpl_draw(graph, pos=layout) + + and with the graphviz drawer: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import graphviz_draw + + graph = retworkx.random_geometric_graph(15, 1.42) + layout = retworkx.spring_layout(graph, adaptive_cooling=False) + for i in range(15): + graph[i] = i + + def node_attr_fn(node): + point = layout[node] + return { + "shape": "circle", + "pos": '"%s,%s!"' % (point[0], point[1]), + "fillcolor": "yellow", + "style": "filled", + "fixedsize": "true" + } + + graphviz_draw(graph, node_attr_fn=node_attr_fn, method='fdp') From e0d59e7dc22e336beeec652d8b2fc26e46da9d1a Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Mon, 31 May 2021 18:19:54 -0400 Subject: [PATCH 20/21] Add examples to random layout --- .../add-random-layout-c1c2751be971e5d0.yaml | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml b/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml index dfd68932de..5a4b9bf815 100644 --- a/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml +++ b/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml @@ -4,7 +4,41 @@ features: Added a new layout function, :func:`retworkx.random_layout` (and it's equivalent per type variants :func:`retworkx.graph_random_layout` and :func:`retworkx.diraph_random_layout`) to generate a random layout which - can be used for visualizations. + can be used for visualizations. For example: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import mpl_draw + + graph = retworkx.generators.directed_grid_graph(5, 5) + layout = retworkx.random_layout(graph) + mpl_draw(graph, pos=layout) + + or with the :func:`~retworkx.visualization.graphviz_draw` function: + + .. jupyter-execute:: + + import retworkx + from retworkx.visualization import graphviz_draw + + graph = retworkx.generators.directed_grid_graph(5, 5) + layout = retworkx.random_layout(graph) + for i in range(25): + graph[i] = i + + def node_attr_fn(node): + point = layout[node] + return { + "shape": "circle", + "pos": '"%s,%s!"' % (point[0], point[1]), + "fillcolor": "yellow", + "style": "filled", + "fixedsize": "true" + } + + graphviz_draw(graph, node_attr_fn=node_attr_fn, method='fdp') + - | A new custom return class, :class:`retworkx.Pos2DMapping`, has been added. This function will be returned by layout functions and is a drop From 72c9830a633f9afd6a0a037d898ccd58f33063ed Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 1 Jun 2021 05:53:07 -0400 Subject: [PATCH 21/21] Update add-random-layout-c1c2751be971e5d0.yaml --- .../notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml b/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml index 5a4b9bf815..34b8838cf0 100644 --- a/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml +++ b/releasenotes/notes/0.9.0/add-random-layout-c1c2751be971e5d0.yaml @@ -41,7 +41,7 @@ features: - | A new custom return class, :class:`retworkx.Pos2DMapping`, has been - added. This function will be returned by layout functions and is a drop + added. This class will be returned by layout functions and is a drop in replacement for an immutable read-only dictionary of the form:: {1: [0.1, 0.5]}