From f6f2ef2799e44bebf198bab89855f437347b4da8 Mon Sep 17 00:00:00 2001
From: Bas Nijholt <basnijholt@gmail.com>
Date: Fri, 19 Oct 2018 16:32:33 +0200
Subject: [PATCH] add a 3D plot using plotly

---
 adaptive/learner/learnerND.py | 67 +++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/adaptive/learner/learnerND.py b/adaptive/learner/learnerND.py
index 4c37b069..93d59f5f 100644
--- a/adaptive/learner/learnerND.py
+++ b/adaptive/learner/learnerND.py
@@ -645,7 +645,7 @@ class LearnerND(BaseLearner):
             )
 
         return vertices, faces
-    
+
     def _get_isoline(self, level=0.0):
         # Very similar to _get_isosurface, maybe merge the two functions
         if self.ndim != 2 or self.vdim != 1:
@@ -723,7 +723,7 @@ class LearnerND(BaseLearner):
             plot = hv.Path([])
         else:
             plot = self.plot(n=n, tri_alpha=tri_alpha)
-        
+
         if isinstance(level, Iterable):
             for l in level:
                 plot = plot * self.plot_isoline(level=l, n=-1)
@@ -804,3 +804,66 @@ class LearnerND(BaseLearner):
         return plotly.graph_objs.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k,
                                         facecolor=colors, opacity=opacity,
                                         lighting=lighting)
+
+    def plot_3D(self, with_triangulation=True):
+        """Plot the learner's data in 3D using plotly.
+
+        Parameters
+        ----------
+        with_triangulation : bool, default: True
+            Add the verticices to the plot.
+
+        Returns
+        -------
+        plot : plotly.offline.iplot object
+            The 3D plot of ``learner.data``.
+        """
+        plotly = ensure_plotly()
+
+        plots = []
+
+        vertices = self.tri.vertices
+        if with_triangulation:
+            Xe, Ye, Ze = [], [], []
+            for simplex in self.tri.simplices:
+                for s in itertools.combinations(simplex, 2):
+                    Xe += [vertices[i][0] for i in s] + [None]
+                    Ye += [vertices[i][1] for i in s] + [None]
+                    Ze += [vertices[i][2] for i in s] + [None]
+
+            plots.append(plotly.graph_objs.Scatter3d(
+                x=Xe, y=Ye, z=Ze, mode='lines',
+                line=dict(color='rgb(125,125,125)', width=1),
+                hoverinfo='none'
+            ))
+
+        Xn, Yn, Zn = zip(*vertices)
+        colors = [self.data[p] for p in self.tri.vertices]
+        marker = dict(symbol='circle', size=3, color=colors,
+            colorscale='Viridis',
+            line=dict(color='rgb(50,50,50)', width=0.5))
+
+        plots.append(plotly.graph_objs.Scatter3d(
+            x=Xn, y=Yn, z=Zn, mode='markers',
+            name='actors', marker=marker,
+            hoverinfo='text'
+        ))
+
+        axis = dict(
+            showbackground=False,
+            showline=False,
+            zeroline=False,
+            showgrid=False,
+            showticklabels=False,
+            title='',
+        )
+
+        layout = plotly.graph_objs.Layout(
+            showlegend=False,
+            scene=dict(xaxis=axis, yaxis=axis, zaxis=axis),
+            margin=dict(t=100),
+            hovermode='closest')
+
+        fig = plotly.graph_objs.Figure(data=plots, layout=layout)
+
+        return plotly.offline.iplot(fig)
-- 
GitLab