Repository: networkx/networkx

Issue:
failure when testing prereleases of dependencies
@rossbar We are getting the following failure when testing prereleases.  I suspect the issue is related to NumPy 1.22.0rc1.
```
=================================== FAILURES ===================================
________________________ TestLayout.test_spiral_layout _________________________

self = <networkx.drawing.tests.test_layout.TestLayout object at 0x7f4dd807dc70>

    def test_spiral_layout(self):
    
        G = self.Gs
    
        # a lower value of resolution should result in a more compact layout
        # intuitively, the total distance from the start and end nodes
        # via each node in between (transiting through each) will be less,
        # assuming rescaling does not occur on the computed node positions
        pos_standard = nx.spiral_layout(G, resolution=0.35)
        pos_tighter = nx.spiral_layout(G, resolution=0.34)
        distances = self.collect_node_distances(pos_standard)
        distances_tighter = self.collect_node_distances(pos_tighter)
>       assert sum(distances) > sum(distances_tighter)
E       assert 2.1859271805707814 > 2.4246843231297848
E        +  where 2.1859271805707814 = sum([0.31927215741496506, 0.3558859513351378, 0.4196367596771466, 0.5002552444945128, 0.5908770676490193])
E        +  and   2.4246843231297848 = sum([0.3585779234394243, 0.39751744460128174, 0.4657296446767588, 0.5524763132328394, 0.6503829971794806])

networkx/drawing/tests/test_layout.py:374: AssertionError
```


Discussion:
```
Package            Version
------------------ -----------
attrs              21.2.0
certifi            2021.10.8
charset-normalizer 2.0.8
codecov            2.1.12
coverage           6.1.2
cycler             0.11.0
fonttools          4.28.2
idna               3.3
iniconfig          1.1.1
kiwisolver         1.3.2
matplotlib         3.5.0
networkx           2.7rc1.dev0
numpy              1.22.0rc1
packaging          21.3
pandas             1.3.4
Pillow             8.4.0
pip                21.3.1
pluggy             1.0.0
py                 1.11.0
pyparsing          3.0.6
pytest             6.2.5
pytest-cov         3.0.0
python-dateutil    2.8.2
pytz               2021.3
requests           2.26.0
scipy              1.7.3
setuptools         59.2.0
setuptools-scm     6.3.2
six                1.16.0
toml               0.10.2
tomli              1.2.2
urllib3            1.26.7
wheel              0.37.0
```
I was trying to look into this (because I that https://github.com/numpy/numpy/issues/20455 might be the reason), but I can't reproduce the failure with NumPy main locally?   Do you happen to have an idea what else could be the reason?  SciPy 1.7.3 is pretty very new?
Hmm.  I can't reproduce the error either.  Maybe it is an Ubuntu issue (it is failing on Ubuntu and I run Fedora).  Here is the failure:
https://github.com/networkx/networkx/runs/4357336292?check_suite_focus=true
I wasn't able to reproduce locally either. I'm curious about what's going
on, but likely won't have a chance to look at it before Wednesday.

On Mon, Nov 29, 2021, 10:11 AM Jarrod Millman ***@***.***>
wrote:

> Hmm. I can't reproduce the error either. Maybe it is an Ubuntu issue (it
> is failing on Ubuntu and I run Fedora).
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/networkx/networkx/issues/5202#issuecomment-981887829>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAJVZ75BS6HFSODKNRB3HPDUOO66XANCNFSM5IYYDI2Q>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>


Resolving patch:
diff --git a/networkx/drawing/layout.py b/networkx/drawing/layout.py
--- a/networkx/drawing/layout.py
+++ b/networkx/drawing/layout.py
@@ -1009,17 +1009,9 @@ def spiral_layout(G, scale=1, center=None, dim=2, resolution=0.35, equidistant=F
             pos.append([np.cos(theta) * r, np.sin(theta) * r])
 
     else:
-        # set the starting angle and step
-        step = 1
-        angle = 0.0
-        dist = 0.0
-        # set the radius for the spiral to the number of nodes in the graph
-        radius = len(G)
-
-        while dist * np.hypot(np.cos(angle), np.sin(angle)) < radius:
-            pos.append([dist * np.cos(angle), dist * np.sin(angle)])
-            dist += step
-            angle += resolution
+        dist = np.arange(len(G), dtype=float)
+        angle = resolution * dist
+        pos = np.transpose(dist * np.array([np.cos(angle), np.sin(angle)]))
 
     pos = rescale_layout(np.array(pos), scale=scale) + center
 


Test patch:
diff --git a/networkx/drawing/tests/test_layout.py b/networkx/drawing/tests/test_layout.py
--- a/networkx/drawing/tests/test_layout.py
+++ b/networkx/drawing/tests/test_layout.py
@@ -15,17 +15,6 @@ def setup_class(cls):
         nx.add_path(cls.Gs, "abcdef")
         cls.bigG = nx.grid_2d_graph(25, 25)  # > 500 nodes for sparse
 
-    @staticmethod
-    def collect_node_distances(positions):
-        distances = []
-        prev_val = None
-        for k in positions:
-            if prev_val is not None:
-                diff = positions[k] - prev_val
-                distances.append((diff @ diff) ** 0.5)
-            prev_val = positions[k]
-        return distances
-
     def test_spring_fixed_without_pos(self):
         G = nx.path_graph(4)
         pytest.raises(ValueError, nx.spring_layout, G, fixed=[0])
@@ -367,20 +356,20 @@ def test_spiral_layout(self):
         # intuitively, the total distance from the start and end nodes
         # via each node in between (transiting through each) will be less,
         # assuming rescaling does not occur on the computed node positions
-        pos_standard = nx.spiral_layout(G, resolution=0.35)
-        pos_tighter = nx.spiral_layout(G, resolution=0.34)
-        distances = self.collect_node_distances(pos_standard)
-        distances_tighter = self.collect_node_distances(pos_tighter)
+        pos_standard = np.array(list(nx.spiral_layout(G, resolution=0.35).values()))
+        pos_tighter = np.array(list(nx.spiral_layout(G, resolution=0.34).values()))
+        distances = np.linalg.norm(pos_standard[:-1] - pos_standard[1:], axis=1)
+        distances_tighter = np.linalg.norm(pos_tighter[:-1] - pos_tighter[1:], axis=1)
         assert sum(distances) > sum(distances_tighter)
 
         # return near-equidistant points after the first value if set to true
-        pos_equidistant = nx.spiral_layout(G, equidistant=True)
-        distances_equidistant = self.collect_node_distances(pos_equidistant)
-        for d in range(1, len(distances_equidistant) - 1):
-            # test similarity to two decimal places
-            assert distances_equidistant[d] == pytest.approx(
-                distances_equidistant[d + 1], abs=1e-2
-            )
+        pos_equidistant = np.array(list(nx.spiral_layout(G, equidistant=True).values()))
+        distances_equidistant = np.linalg.norm(
+            pos_equidistant[:-1] - pos_equidistant[1:], axis=1
+        )
+        assert np.allclose(
+            distances_equidistant[1:], distances_equidistant[-1], atol=0.01
+        )
 
     def test_rescale_layout_dict(self):
         G = nx.empty_graph()