@@ -1464,11 +1464,10 @@ def _find_intermediate_color(lowcolor, highcolor, intermed):
1464
1464
diff_1 = float(highcolor[1] - lowcolor[1])
1465
1465
diff_2 = float(highcolor[2] - lowcolor[2])
1466
1466
1467
- new_tuple = (lowcolor[0] + intermed*diff_0,
1468
- lowcolor[1] + intermed*diff_1,
1469
- lowcolor[2] + intermed*diff_2)
1470
-
1471
- return new_tuple
1467
+ inter_colors = np.array([lowcolor[0] + intermed * diff_0,
1468
+ lowcolor[1] + intermed * diff_1,
1469
+ lowcolor[2] + intermed * diff_2])
1470
+ return inter_colors
1472
1471
1473
1472
@staticmethod
1474
1473
def _unconvert_from_RGB_255(colors):
@@ -1491,7 +1490,7 @@ def _unconvert_from_RGB_255(colors):
1491
1490
return un_rgb_colors
1492
1491
1493
1492
@staticmethod
1494
- def _map_z2color(zval , colormap, vmin, vmax):
1493
+ def _map_z2color(zvals , colormap, vmin, vmax):
1495
1494
"""
1496
1495
Returns the color corresponding zval's place between vmin and vmax
1497
1496
@@ -1508,21 +1507,14 @@ def _map_z2color(zval, colormap, vmin, vmax):
1508
1507
"of vmax.")
1509
1508
# find distance t of zval from vmin to vmax where the distance
1510
1509
# is normalized to be between 0 and 1
1511
- t = (zval - vmin)/float((vmax - vmin))
1512
- t_color = FigureFactory._find_intermediate_color(colormap[0],
1513
- colormap[1],
1514
- t)
1515
- t_color = (t_color[0]*255.0, t_color[1]*255.0, t_color[2]*255.0)
1516
- labelled_color = 'rgb{}'.format(t_color)
1517
-
1518
- return labelled_color
1519
-
1520
- @staticmethod
1521
- def _tri_indices(simplices):
1522
- """
1523
- Returns a triplet of lists containing simplex coordinates
1524
- """
1525
- return ([triplet[c] for triplet in simplices] for c in range(3))
1510
+ t = (zvals - vmin) / float((vmax - vmin))
1511
+ t_colors = FigureFactory._find_intermediate_color(colormap[0],
1512
+ colormap[1],
1513
+ t)
1514
+ t_colors = t_colors * 255.
1515
+ labelled_colors = ['rgb(%s, %s, %s)' % (i, j, k)
1516
+ for i, j, k in t_colors.T]
1517
+ return labelled_colors
1526
1518
1527
1519
@staticmethod
1528
1520
def _trisurf(x, y, z, simplices, colormap=None, dist_func=None,
@@ -1539,11 +1531,11 @@ def _trisurf(x, y, z, simplices, colormap=None, dist_func=None,
1539
1531
points3D = np.vstack((x, y, z)).T
1540
1532
1541
1533
# vertices of the surface triangles
1542
- tri_vertices = list(map(lambda index: points3D[index], simplices))
1534
+ tri_vertices = points3D[simplices]
1543
1535
1544
1536
if not dist_func:
1545
1537
# mean values of z-coordinates of triangle vertices
1546
- mean_dists = [np.mean(tri[ :, 2]) for tri in tri_vertices]
1538
+ mean_dists = tri_vertices[ :, :, 2].mean(-1)
1547
1539
else:
1548
1540
# apply user inputted function to calculate
1549
1541
# custom coloring for triangle vertices
@@ -1559,38 +1551,47 @@ def _trisurf(x, y, z, simplices, colormap=None, dist_func=None,
1559
1551
1560
1552
min_mean_dists = np.min(mean_dists)
1561
1553
max_mean_dists = np.max(mean_dists)
1562
- facecolor = ([ FigureFactory._map_z2color(zz , colormap, min_mean_dists ,
1563
- max_mean_dists) for zz in mean_dists] )
1564
- ii, jj, kk = FigureFactory._tri_indices( simplices)
1554
+ facecolor = FigureFactory._map_z2color(mean_dists , colormap,
1555
+ min_mean_dists, max_mean_dists )
1556
+ ii, jj, kk = zip(* simplices)
1565
1557
1566
1558
triangles = graph_objs.Mesh3d(x=x, y=y, z=z, facecolor=facecolor,
1567
1559
i=ii, j=jj, k=kk, name='')
1568
1560
1569
- if plot_edges is None : # the triangle sides are not plotted
1561
+ if plot_edges is not True : # the triangle sides are not plotted
1570
1562
return graph_objs.Data([triangles])
1571
1563
1572
1564
# define the lists x_edge, y_edge and z_edge, of x, y, resp z
1573
1565
# coordinates of edge end points for each triangle
1574
1566
# None separates data corresponding to two consecutive triangles
1575
- lists_coord = ([[[T[k % 3][c] for k in range(4)]+[None]
1576
- for T in tri_vertices] for c in range(3)])
1577
- if x_edge is None:
1578
- x_edge = []
1579
- for array in lists_coord[0]:
1580
- for item in array:
1581
- x_edge.append(item)
1582
-
1583
- if y_edge is None:
1584
- y_edge = []
1585
- for array in lists_coord[1]:
1586
- for item in array:
1587
- y_edge.append(item)
1588
-
1589
- if z_edge is None:
1590
- z_edge = []
1591
- for array in lists_coord[2]:
1592
- for item in array:
1593
- z_edge.append(item)
1567
+ is_none = [ii is None for ii in [x_edge, y_edge, z_edge]]
1568
+ if any(is_none):
1569
+ if not all(is_none):
1570
+ raise ValueError("If any (x_edge, y_edge, z_edge) is None, "
1571
+ "all must be None")
1572
+ else:
1573
+ x_edge = []
1574
+ y_edge = []
1575
+ z_edge = []
1576
+
1577
+ # Pull indices we care about, then add a None column to separate tris
1578
+ ixs_triangles = [0, 1, 2, 0]
1579
+ pull_edges = tri_vertices[:, ixs_triangles, :]
1580
+ x_edge_pull = np.hstack([pull_edges[:, :, 0],
1581
+ np.tile(None, [pull_edges.shape[0], 1])])
1582
+ y_edge_pull = np.hstack([pull_edges[:, :, 1],
1583
+ np.tile(None, [pull_edges.shape[0], 1])])
1584
+ z_edge_pull = np.hstack([pull_edges[:, :, 2],
1585
+ np.tile(None, [pull_edges.shape[0], 1])])
1586
+
1587
+ # Now unravel the edges into a 1-d vector for plotting
1588
+ x_edge = np.hstack([x_edge, x_edge_pull.reshape([1, -1])[0]])
1589
+ y_edge = np.hstack([y_edge, y_edge_pull.reshape([1, -1])[0]])
1590
+ z_edge = np.hstack([z_edge, z_edge_pull.reshape([1, -1])[0]])
1591
+
1592
+ if not (len(x_edge) == len(y_edge) == len(z_edge)):
1593
+ raise exceptions.PlotlyError("The lengths of x_edge, y_edge and "
1594
+ "z_edge are not the same.")
1594
1595
1595
1596
# define the lines for plotting
1596
1597
lines = graph_objs.Scatter3d(
@@ -5621,4 +5622,3 @@ def make_table_annotations(self):
5621
5622
font=dict(color=font_color),
5622
5623
showarrow=False))
5623
5624
return annotations
5624
-
0 commit comments