Repository: mikedh/trimesh

Issue:
Where's scene.graph.show() gone?
Hi,
It used to be possible to do `scene.graph.show()` with a trimesh scene. It would show a transformation graph of the scene in a new window.
This functionality seems to be broken now. I think since https://github.com/mikedh/trimesh/pull/1221 or similar.
What's the new way to achieve the same?

Thanks!

Discussion:

Patch:
diff --git a/README.md b/README.md
index ac8094c3..e6998864 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,7 @@
 [![trimesh](https://trimsh.org/images/logotype-a.svg)](http://trimsh.org)
 
 -----------
-[![Github Actions](https://github.com/mikedh/trimesh/workflows/Release%20Trimesh/badge.svg)](https://github.com/mikedh/trimesh/actions)  [![PyPI version](https://badge.fury.io/py/trimesh.svg)](https://badge.fury.io/py/trimesh) [![Join the chat at https://gitter.im/trimsh/Lobby](https://badges.gitter.im/trimsh/Lobby.svg)](https://gitter.im/trimsh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
+[![Github Actions](https://github.com/mikedh/trimesh/workflows/Release%20Trimesh/badge.svg)](https://github.com/mikedh/trimesh/actions)  [![PyPI version](https://badge.fury.io/py/trimesh.svg)](https://badge.fury.io/py/trimesh) [![codecov](https://codecov.io/gh/mikedh/trimesh/branch/master/graph/badge.svg?token=4PVRQXyl2h)](https://codecov.io/gh/mikedh/trimesh)
 
 
 Trimesh is a pure Python (2.7-3.4+) library for loading and using [triangular meshes](https://en.wikipedia.org/wiki/Triangle_mesh) with an emphasis on watertight surfaces. The goal of the library is to provide a full featured and well tested Trimesh object which allows for easy manipulation and analysis, in the style of the Polygon object in the [Shapely library](https://github.com/Toblerity/Shapely).
diff --git a/trimesh/scene/transforms.py b/trimesh/scene/transforms.py
index 68c39788..507b1ded 100644
--- a/trimesh/scene/transforms.py
+++ b/trimesh/scene/transforms.py
@@ -338,6 +338,43 @@ class SceneGraph(object):
                 raise ValueError(
                     'edge incorrect shape: %s', str(edge))
 
+    def to_networkx(self):
+        """
+        Return a `networkx` copy of this graph.
+
+        Returns
+        ----------
+        graph : networkx.DiGraph
+          Directed graph.
+        """
+        import networkx
+        return networkx.from_edgelist(
+            self.to_edgelist(),
+            create_using=networkx.DiGraph)
+
+    def show(self, **kwargs):
+        """
+        Plot the scene graph using `networkx.draw_networkx`
+        which uses matplotlib to display the graph.
+
+        Parameters
+        -----------
+        kwargs : dict
+          Passed to `networkx.draw_networkx`
+        """
+        import networkx
+        import matplotlib.pyplot as plt
+        # default kwargs will only be set if not
+        # passed explicitly to the show command
+        defaults = {'with_labels': True}
+        kwargs.update(**{k: v for k, v in defaults.items()
+                         if k not in kwargs})
+        networkx.draw_networkx(
+            G=self.to_networkx(),
+            **kwargs)
+
+        plt.show()
+
     def load(self, edgelist):
         """
         Load transform data from an edge list into the current
diff --git a/trimesh/version.py b/trimesh/version.py
index cb63a1c4..84fb14cc 100644
--- a/trimesh/version.py
+++ b/trimesh/version.py
@@ -1,1 +1,1 @@
-__version__ = '3.9.23'
+__version__ = '3.9.24'


Test patch:
diff --git a/tests/generic.py b/tests/generic.py
index 1862b995..6c4a3989 100644
--- a/tests/generic.py
+++ b/tests/generic.py
@@ -80,6 +80,11 @@ except BaseException as E:
     if all_dep:
         raise E
 
+try:
+    import networkx as nx
+except BaseException as E:
+    pass
+
 # find_executable for binvox
 has_binvox = trimesh.exchange.binvox.binvox_encoder is not None
 
diff --git a/tests/test_scenegraph.py b/tests/test_scenegraph.py
index e15e6dad..21728c59 100644
--- a/tests/test_scenegraph.py
+++ b/tests/test_scenegraph.py
@@ -13,9 +13,9 @@ def random_chr():
 class GraphTests(g.unittest.TestCase):
 
     def test_forest(self):
-        g = EnforcedForest()
+        graph = EnforcedForest()
         for i in range(5000):
-            g.add_edge(random_chr(), random_chr())
+            graph.add_edge(random_chr(), random_chr())
 
     def test_cache(self):
         for i in range(10):
@@ -60,6 +60,9 @@ class GraphTests(g.unittest.TestCase):
         assert len(ss.geometry) == 1
         assert len(ss.graph.nodes_geometry) == 1
 
+        assert isinstance(s.graph.to_networkx(),
+                          g.nx.DiGraph)
+
     def test_kwargs(self):
         # test the function that converts various
         # arguments into a homogenous transformation