Repository: networkx/networkx

Issue:
Question: behavior of `node_list` kwarg in draw_networkx_edges
Like the other pylab drawing functions, `nx_pylab.draw_networkx_edges` currently has a `nodelist` keyword argument. It is not included in the `Parameters` listing of the docstring and so it's behavior is not well-defined. 

Naively, I would expect that any edges incident on a node *not* in the node list would not be drawn. For example, I would expect the following:

```python
>>> G = nx.path_graph(3)
>>> pos = {n: (n, n) for n in range(len(G))}
>>> nx.draw_networkx_nodes(G, pos, nodelist=[0, 1])
>>> nx.draw_networkx_edges(G, pos, nodelist=[0, 1])
```
to produce the following, without the edge (1, 2) since 2 was not included in the nodelist:

![expected](https://user-images.githubusercontent.com/1268991/99858963-8f2fa680-2b43-11eb-8292-bad080df0456.png)

Instead, the above code results in the following image:

![reality](https://user-images.githubusercontent.com/1268991/99859092-e3d32180-2b43-11eb-9d6c-c701c4766dd7.png)

Is this expected? Right now, the `nodelist` is only used internally in `draw_networkx_edges` to determine the size of the nodes. Either way, the parameter needs to be added to the docstring and the behavior tested - I just wanted to raise the question about what the desired behavior was in order to do so!


Discussion:
@rossbar I agree with you.  Edges should only be drawn if both endpoints are in the graph.

Resolving patch:
diff --git a/networkx/drawing/nx_pylab.py b/networkx/drawing/nx_pylab.py
--- a/networkx/drawing/nx_pylab.py
+++ b/networkx/drawing/nx_pylab.py
@@ -556,6 +556,19 @@ def draw_networkx_edges(
        See `matplotlib.patches.ConnectionStyle` and
        `matplotlib.patches.FancyArrowPatch` for more info.
 
+    node_size : scalar or array, optional (default=300)
+       Size of nodes. Though the nodes are not drawn with this function, the
+       node size is used in determining edge positioning.
+
+    nodelist : list, optional (default=G.nodes())
+       Only draw edges that are in `edgelist` and that lie between nodes in
+       `nodelist`. Any edges in `edgelist` incident on nodes that are *not* in
+       `nodelist` will not be drawn.
+
+    node_shape :  string, optional (default='o')
+       The marker used for nodes, used in determining edge positioning.
+       Specification is as a `matplotlib.markers` marker, e.g. one of 'so^>v<dph8'.
+
     label : [None| string]
        Label for legend
 
@@ -628,11 +641,15 @@ def draw_networkx_edges(
     if edgelist is None:
         edgelist = list(G.edges())
 
-    if len(edgelist) == 0:  # no edges!
-        return []
-
     if nodelist is None:
         nodelist = list(G.nodes())
+    else:
+        # Remove any edges where both endpoints are not in node list
+        nodeset = set(nodelist)
+        edgelist = [(u, v) for u, v in edgelist if (u in nodeset) and (v in nodeset)]
+
+    if len(edgelist) == 0:  # no edges!
+        return []
 
     # FancyArrowPatch handles color=None different from LineCollection
     if edge_color is None:


Test patch:
diff --git a/networkx/drawing/tests/test_pylab.py b/networkx/drawing/tests/test_pylab.py
--- a/networkx/drawing/tests/test_pylab.py
+++ b/networkx/drawing/tests/test_pylab.py
@@ -312,6 +312,8 @@ def test_draw_edges_min_source_target_margins(node_shape):
     assert padded_extent[0] > default_extent[0]
     # And the rightmost extent of the edge, further to the left
     assert padded_extent[1] < default_extent[1]
+    # NOTE: Prevent axes objects from impacting other tests via plt.gca
+    plt.delaxes(ax)
 
 
 def test_apply_alpha():
@@ -323,3 +325,21 @@ def test_apply_alpha():
     alpha = 0.5
     rgba_colors = nx.drawing.nx_pylab.apply_alpha(colorlist, alpha, nodelist)
     assert all(rgba_colors[:, -1] == alpha)
+
+
+@pytest.mark.parametrize(
+    ("nodelist", "expected_num_edges"),
+    (
+        ([], 0),
+        ([1], 0),
+        ([1, 2], 1),
+        ([0, 1, 2, 3], 6),
+    ),
+)
+def test_draw_edges_with_nodelist(nodelist, expected_num_edges):
+    """Test that edges that contain a node in `nodelist` are not drawn by
+    draw_networkx_edges. See gh-4374.
+    """
+    G = nx.complete_graph(5)
+    edge_patches = nx.draw_networkx_edges(G, nx.circular_layout(G), nodelist=nodelist)
+    assert len(edge_patches) == expected_num_edges