summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Barnowski <rossbar@berkeley.edu>2021-09-14 22:40:59 -0500
committerGitHub <noreply@github.com>2021-09-14 23:40:59 -0400
commitd7fc10144c624c4ae7fc1c3bc9df7d7a3c563984 (patch)
treee42c2001cc1463cedd6ca13c179b77fd7aee15ff
parent4e31e9ee035333d60e02cee4599d7de31ec097a9 (diff)
downloadnetworkx-d7fc10144c624c4ae7fc1c3bc9df7d7a3c563984.tar.gz
Minor updates to tutorial.rst and add docstring for data method of nodes/edges (#5039)
* Rm statement about None as sentinel in Graph. * Add links to graph gens and readwrite. * Add links to adjacency reporting properties. * Rm span kwarg from tutorial example. Doesn't make sense without more context. * Add docstring for the NodeView.data method. * Add docstring for EdgeView.data method * Add adj dict constructor example. * Rework some links and add others in DiGraph section. * Fix autosummary links in tutorial. * Add headings to graph generator ennumerations. The enumeration was broken anyways, and this at least makes the headings more visible and gives them html anchors. * Add some links to drawing section. * A few more drawing links. * Fix doctest. * Wording update from review.
-rw-r--r--doc/tutorial.rst103
-rw-r--r--networkx/classes/reportviews.py134
2 files changed, 194 insertions, 43 deletions
diff --git a/doc/tutorial.rst b/doc/tutorial.rst
index 8f1a1705..ca496560 100644
--- a/doc/tutorial.rst
+++ b/doc/tutorial.rst
@@ -22,13 +22,14 @@ another Graph, a customized node object, etc.
.. note:: Python's ``None`` object is not allowed to be used as a node. It
determines whether optional function arguments have been assigned in many
- functions. And it can be used as a sentinel object meaning "not a node".
+ functions.
Nodes
-----
-The graph ``G`` can be grown in several ways. NetworkX includes many graph
-generator functions and facilities to read and write graphs in many formats.
+The graph ``G`` can be grown in several ways. NetworkX includes many
+:doc:`graph generator functions <reference/generators>` and
+:doc:`facilities to read and write graphs in many formats <reference/readwrite/index>`.
To get started though we'll look at simple manipulations. You can add one node
at a time,
@@ -134,9 +135,10 @@ At this stage the graph ``G`` consists of 8 nodes and 3 edges, as can be seen by
.. note::
- The order of adjacency reporting (e.g., G.adj, G.successors,
- G.predecessors) is the order of edge addition. However,
- the order of G.edges is the order of the adjacencies
+ The order of adjacency reporting (e.g., :meth:`G.adj <networkx.Graph.adj>`,
+ :meth:`G.successors <networkx.DiGraph.successors>`,
+ :meth:`G.predecessors <networkx.DiGraph.predecessors>`) is the order of
+ edge addition. However, the order of G.edges is the order of the adjacencies
which includes both the order of the nodes and each
node's adjacencies. See example below:
@@ -159,7 +161,7 @@ are set-like views of the nodes, edges, neighbors (adjacencies), and degrees
of nodes in a graph. They offer a continually updated read-only view into
the graph structure. They are also dict-like in that you can look up node
and edge data attributes via the views and iterate with data attributes
-using methods ``.items()``, ``.data('span')``.
+using methods ``.items()``, ``.data()``.
If you want a specific container type instead of a view, you can specify one.
Here we use lists, though sets, dicts, tuples and other containers may be
better in other contexts.
@@ -218,11 +220,17 @@ classes you can specify data in several formats.
.. nbplot::
>>> G.add_edge(1, 2)
- >>> H = nx.DiGraph(G) # create a DiGraph using the connections from G
+ >>> H = nx.DiGraph(G) # create a DiGraph using the connections from G
>>> list(H.edges())
[(1, 2), (2, 1)]
>>> edgelist = [(0, 1), (1, 2), (2, 3)]
- >>> H = nx.Graph(edgelist)
+ >>> H = nx.Graph(edgelist) # create a graph from an edge list
+ >>> list(H.edges())
+ [(0, 1), (1, 2), (2, 3)]
+ >>> adjacency_dict = {0: (1, 2), 1: (0, 2), 2: (0, 1)}
+ >>> H = nx.Graph(adjacency_dict) # create a Graph dict mapping nodes to nbrs
+ >>> list(H.edges())
+ [(0, 1), (0, 2), (1, 2)]
What to use as nodes and edges
------------------------------
@@ -370,11 +378,11 @@ Directed graphs
The :class:`DiGraph` class provides additional methods and properties specific
to directed edges, e.g.,
:attr:`DiGraph.out_edges`, :attr:`DiGraph.in_degree`,
-:meth:`DiGraph.predecessors`, :meth:`DiGraph.successors` etc.
+`DiGraph.predecessors`, `DiGraph.successors` etc.
To allow algorithms to work with both classes easily, the directed versions of
-``neighbors()`` is equivalent to ``successors()`` while ``degree`` reports
-the sum of ``in_degree`` and ``out_degree`` even though that may feel
-inconsistent at times.
+:meth:`neighbors <DiGraph.neighbors>` is equivalent to
+`successors <DiGraph.successors>` while `~DiGraph.degree` reports the sum
+of `~DiGraph.in_degree` and `~DiGraph.out_degree` even though that may feel inconsistent at times.
.. nbplot::
@@ -435,36 +443,39 @@ In addition to constructing graphs node-by-node or edge-by-edge, they
can also be generated by
1. Applying classic graph operations, such as:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autosummary::
- subgraph - induced subgraph view of G on nodes in nbunch
- union - graph union
- disjoint_union - graph union assuming all nodes are different
- cartesian_product - return Cartesian product graph
- compose - combine graphs identifying nodes common to both
- complement - graph complement
- create_empty_copy - return an empty copy of the same graph class
- to_undirected - return an undirected representation of G
- to_directed - return a directed representation of G
+ ~networkx.classes.function.subgraph
+ ~networkx.algorithms.operators.binary.union
+ ~networkx.algorithms.operators.binary.disjoint_union
+ ~networkx.algorithms.operators.product.cartesian_product
+ ~networkx.algorithms.operators.binary.compose
+ ~networkx.algorithms.operators.unary.complement
+ ~networkx.classes.function.create_empty_copy
+ ~networkx.classes.function.to_undirected
+ ~networkx.classes.function.to_directed
2. Using a call to one of the classic small graphs, e.g.,
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autosummary::
- petersen_graph
- tutte_graph
- sedgewick_maze_graph
- tetrahedral_graph
+ ~networkx.generators.small.petersen_graph
+ ~networkx.generators.small.tutte_graph
+ ~networkx.generators.small.sedgewick_maze_graph
+ ~networkx.generators.small.tetrahedral_graph
3. Using a (constructive) generator for a classic graph, e.g.,
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autosummary::
- complete_graph
- complete_bipartite_graph
- barbell_graph
- lollipop_graph
+ ~networkx.generators.classic.complete_graph
+ ~networkx.algorithms.bipartite.generators.complete_bipartite_graph
+ ~networkx.generators.classic.barbell_graph
+ ~networkx.generators.classic.lollipop_graph
like so:
@@ -476,13 +487,14 @@ like so:
>>> lollipop = nx.lollipop_graph(10, 20)
4. Using a stochastic graph generator, e.g,
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autosummary::
- erdos_renyi_graph
- watts_strogatz_graph
- barabasi_albert_graph
- random_lobster
+ ~networkx.generators.random_graphs.erdos_renyi_graph
+ ~networkx.generators.random_graphs.watts_strogatz_graph
+ ~networkx.generators.random_graphs.barabasi_albert_graph
+ ~networkx.generators.random_graphs.random_lobster
like so:
@@ -493,8 +505,11 @@ like so:
>>> ba = nx.barabasi_albert_graph(100, 5)
>>> red = nx.random_lobster(100, 0.9, 0.9)
-5. Reading a graph stored in a file using common graph formats,
- such as edge lists, adjacency lists, GML, GraphML, pickle, LEDA and others.
+5. Reading a graph stored in a file using common graph formats
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+NetworkX supports many popular formats, such as edge lists, adjacency lists,
+GML, GraphML, pickle, LEDA and others.
.. nbplot::
@@ -539,8 +554,8 @@ Drawing graphs
NetworkX is not primarily a graph drawing package but basic drawing with
Matplotlib as well as an interface to use the open source Graphviz software
-package are included. These are part of the ``networkx.drawing`` module and will
-be imported if possible.
+package are included. These are part of the :doc:`networkx.drawing <reference/drawing>`
+module and will be imported if possible.
First import Matplotlib's plot interface (pylab works too)
@@ -548,7 +563,8 @@ First import Matplotlib's plot interface (pylab works too)
>>> import matplotlib.pyplot as plt
-To test if the import of ``networkx.drawing`` was successful draw ``G`` using one of
+To test if the import of `~networkx.drawing.nx_pylab` was successful draw ``G``
+using one of
.. nbplot::
@@ -583,7 +599,7 @@ command if you are not using matplotlib in interactive mode (see
>>> nx.draw_shell(G, nlist=[range(5,10), range(5)], **options)
You can find additional options via :func:`~drawing.nx_pylab.draw_networkx` and
-layouts via :mod:`layout <networkx.drawing.layout>`.
+layouts via the :mod:`layout module<networkx.drawing.layout>`.
You can use multiple shells with :func:`~drawing.nx_pylab.draw_shell`.
.. nbplot::
@@ -597,10 +613,11 @@ To save drawings to a file, use, for example
>>> nx.draw(G)
>>> plt.savefig("path.png")
-writes to the file ``path.png`` in the local directory. If Graphviz and
+This function writes to the file ``path.png`` in the local directory. If Graphviz and
PyGraphviz or pydot, are available on your system, you can also use
-``nx_agraph.graphviz_layout(G)`` or ``nx_pydot.graphviz_layout(G)`` to get the
-node positions, or write the graph in dot format for further processing.
+`networkx.drawing.nx_agraph.graphviz_layout` or
+`networkx.drawing.nx_pydot.graphviz_layout` to get the node positions, or write
+the graph in dot format for further processing.
>>> from networkx.drawing.nx_pydot import write_dot
>>> pos = nx.nx_agraph.graphviz_layout(G)
diff --git a/networkx/classes/reportviews.py b/networkx/classes/reportviews.py
index d8ae60d8..06d8dfde 100644
--- a/networkx/classes/reportviews.py
+++ b/networkx/classes/reportviews.py
@@ -207,6 +207,67 @@ class NodeView(Mapping, Set):
return NodeDataView(self._nodes, data, default)
def data(self, data=True, default=None):
+ """
+ Return a read-only view of node data.
+
+ Parameters
+ ----------
+ data : bool or node data key, default=True
+ If ``data=True`` (the default), return a `NodeDataView` object that
+ maps each node to *all* of its attributes. `data` may also be an
+ arbitrary key, in which case the `NodeDataView` maps each node to
+ the value for the keyed attribute. In this case, if a node does
+ not have the `data` attribute, the `default` value is used.
+ default : object, default=None
+ The value used when a node does not have a specific attribute.
+
+ Returns
+ -------
+ NodeDataView
+ The layout of the returned NodeDataView depends on the value of the
+ `data` parameter.
+
+ Notes
+ -----
+ If ``data=False``, returns a `NodeView` object without data.
+
+ See Also
+ --------
+ NodeDataView
+
+ Examples
+ --------
+ >>> G = nx.Graph()
+ >>> G.add_nodes_from([
+ ... (0, {"color": "red", "weight": 10}),
+ ... (1, {"color": "blue"}),
+ ... (2, {"color": "yellow", "weight": 2})
+ ... ])
+
+ Accessing node data with ``data=True`` (the default) returns a
+ NodeDataView mapping each node to all of its attributes:
+
+ >>> G.nodes.data()
+ NodeDataView({0: {'color': 'red', 'weight': 10}, 1: {'color': 'blue'}, 2: {'color': 'yellow', 'weight': 2}})
+
+ If `data` represents a key in the node attribute dict, a NodeDataView mapping
+ the nodes to the value for that specific key is returned:
+
+ >>> G.nodes.data("color")
+ NodeDataView({0: 'red', 1: 'blue', 2: 'yellow'}, data='color')
+
+ If a specific key is not found in an attribute dict, the value specified
+ by `default` is returned:
+
+ >>> G.nodes.data("weight", default=-999)
+ NodeDataView({0: 10, 1: -999, 2: 2}, data='weight')
+
+ Note that there is no check that the `data` key is in any of the
+ node attribute dictionaries:
+
+ >>> G.nodes.data("height")
+ NodeDataView({0: None, 1: None, 2: None}, data='height')
+ """
if data is False:
return self
return NodeDataView(self._nodes, data, default)
@@ -1038,6 +1099,79 @@ class OutEdgeView(Set, Mapping):
return self.dataview(self, nbunch, data, default)
def data(self, data=True, default=None, nbunch=None):
+ """
+ Return a read-only view of edge data.
+
+ Parameters
+ ----------
+ data : bool or edge attribute key
+ If ``data=True``, then the data view maps each edge to a dictionary
+ containing all of its attributes. If `data` is a key in the edge
+ dictionary, then the data view maps each edge to its value for
+ the keyed attribute. In this case, if the edge doesn't have the
+ attribute, the `default` value is returned.
+ default : object, default=None
+ The value used when an edge does not have a specific attribute
+ nbunch : container of nodes, optional (default=None)
+ Allows restriction to edges only involving certain nodes. All edges
+ are considered by default.
+
+ Returns
+ -------
+ dataview
+ Returns an `EdgeDataView` for undirected Graphs, `OutEdgeDataView`
+ for DiGraphs, `MultiEdgeDataView` for MultiGraphs and
+ `OutMultiEdgeDataView` for MultiDiGraphs.
+
+ Notes
+ -----
+ If ``data=False``, returns an `EdgeView` without any edge data.
+
+ See Also
+ --------
+ EdgeDataView
+ OutEdgeDataView
+ MultiEdgeDataView
+ OutMultiEdgeDataView
+
+ Examples
+ --------
+ >>> G = nx.Graph()
+ >>> G.add_edges_from([
+ ... (0, 1, {"dist": 3, "capacity": 20}),
+ ... (1, 2, {"dist": 4}),
+ ... (2, 0, {"dist": 5})
+ ... ])
+
+ Accessing edge data with ``data=True`` (the default) returns an
+ edge data view object listing each edge with all of its attributes:
+
+ >>> G.edges.data()
+ EdgeDataView([(0, 1, {'dist': 3, 'capacity': 20}), (0, 2, {'dist': 5}), (1, 2, {'dist': 4})])
+
+ If `data` represents a key in the edge attribute dict, a dataview listing
+ each edge with its value for that specific key is returned:
+
+ >>> G.edges.data("dist")
+ EdgeDataView([(0, 1, 3), (0, 2, 5), (1, 2, 4)])
+
+ `nbunch` can be used to limit the edges:
+
+ >>> G.edges.data("dist", nbunch=[0])
+ EdgeDataView([(0, 1, 3), (0, 2, 5)])
+
+ If a specific key is not found in an edge attribute dict, the value
+ specified by `default` is used:
+
+ >>> G.edges.data("capacity")
+ EdgeDataView([(0, 1, 20), (0, 2, None), (1, 2, None)])
+
+ Note that there is no check that the `data` key is present in any of
+ the edge attribute dictionaries:
+
+ >>> G.edges.data("speed")
+ EdgeDataView([(0, 1, None), (0, 2, None), (1, 2, None)])
+ """
if nbunch is None and data is False:
return self
return self.dataview(self, nbunch, data, default)