8000 Merge branch 'custom_colors_trisurf' of https://github.com/choldgraf/… · mode/plotly.py@a708df2 · GitHub
[go: up one dir, main page]

Skip to content

Commit a708df2

Browse files
committed
Merge branch 'custom_colors_trisurf' of https://github.com/choldgraf/plotly.py into choldgraf-custom_colors_trisurf
2 parents dfef7af + bed542d commit a708df2

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

plotly/tests/test_optional/test_figure_factory.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,26 @@ def test_trisurf_all_args(self):
752752
self.assert_dict_equal(test_trisurf_plot['data'][1],
753753
exp_trisurf_plot['data'][1])
754754

755+
# Test passing custom colors
756+
colors_raw = np.random.randn(simplices.shape[0])
757+
colors_str = ['rgb(%s, %s, %s)' % (i, j, k)
758+
for i, j, k in np.random.randn(simplices.shape[0], 3)]
759+
760+
# Color == strings should be kept the same
761+
test_colors_plot = tls.FigureFactory.create_trisurf(
762+
x, y, z, simplices, color_func=colors_str)
763+
self.assertListEqual(list(test_colors_plot['data'][0]['facecolor']),
764+
list(colors_str))
765+
# Colors must match length of simplices
766+
colors_bad = colors_str[:-1]
767+
self.assertRaises(ValueError, tls.FigureFactory.create_trisurf, x, y,
768+
z, simplices, color_func=colors_bad)
769+
# Check converting custom colors to strings
770+
test_colors_plot = tls.FigureFactory.create_trisurf(
771+
x, y, z, simplices, color_func=colors_raw)
772+
self.assertTrue(isinstance(test_colors_plot['data'][0]['facecolor'][0],
773+
str))
774+
755775

756776
class TestScatterPlotMatrix(NumpyTestUtilsMixin, TestCase):
757777

plotly/tools.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,11 +1500,11 @@ def _unconvert_from_RGB_255(colors):
15001500
return un_rgb_colors
15011501

15021502
@staticmethod
1503-
def _map_z2color(zvals, colormap, vmin, vmax):
1503+
def _map_array2color(array, colormap, vmin, vmax):
15041504
"""
1505-
Returns the color corresponding zval's place between vmin and vmax
1505+
Normalize values in array by vmin/vmax and return plotly color strings.
15061506
1507-
This function takes a z value (zval) along with a colormap and a
1507+
This function takes an array of values along with a colormap and a
15081508
minimum (vmin) and maximum (vmax) range of possible z values for the
15091509
given parametrized surface. It returns an rgb color based on the
15101510
relative position of zval between vmin and vmax
@@ -1517,7 +1517,7 @@ def _map_z2color(zvals, colormap, vmin, vmax):
15171517
"of vmax.")
15181518
# find distance t of zval from vmin to vmax where the distance
15191519
# is normalized to be between 0 and 1
1520-
t = (zvals - vmin) / float((vmax - vmin))
1520+
t = (array - vmin) / float((vmax - vmin))
15211521
t_colors = FigureFactory._find_intermediate_color(colormap[0],
15221522
colormap[1],
15231523
t)
@@ -1539,34 +1539,46 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
15391539
import numpy as np
15401540
from plotly.graph_objs import graph_objs
15411541
points3D = np.vstack((x, y, z)).T
1542+
simplices = np.atleast_2d(simplices)
15421543

15431544
# vertices of the surface triangles
15441545
tri_vertices = points3D[simplices]
15451546

1546-
if not color_func:
1547+
# Define colors for the triangle faces
1548+
if color_func is None:
15471549
# mean values of z-coordinates of triangle vertices
15481550
mean_dists = tri_vertices[:, :, 2].mean(-1)
1551+
elif isinstance(color_func, (list, np.ndarray)):
1552+
# Pre-computed list / array of values to map onto color
1553+
if len(color_func) != len(simplices):
1554+
raise ValueError('If color_func is a list/array, must'
1555+
' be the same length as simplices')
1556+
mean_dists = np.asarray(color_func)
15491557
else:
15501558
# apply user inputted function to calculate
15511559
# custom coloring for triangle vertices
15521560
mean_dists = []
1553-
15541561
for triangle in tri_vertices:
15551562
dists = []
15561563
for vertex in triangle:
15571564
dist = color_func(vertex[0], vertex[1], vertex[2])
15581565
dists.append(dist)
1559-
15601566
mean_dists.append(np.mean(dists))
1567+
mean_dists = np.asarray(mean_dists)
15611568

1562-
min_mean_dists = np.min(mean_dists)
1563-
max_mean_dists = np.max(mean_dists)
1564-
facecolor = FigureFactory._map_z2color(mean_dists,
1565-
colormap,
1566-
min_mean_dists,
1567-
max_mean_dists)
1568-
1569-
ii, jj, kk = zip(*simplices)
1569+
# Check if facecolors are already strings and can be skipped
1570+
if isinstance(mean_dists[0], str):
1571+
facecolor = mean_dists
1572+
else:
1573+
min_mean_dists = np.min(mean_dists)
1574+
max_mean_dists = np.max(mean_dists)
1575+
facecolor = FigureFactory._map_array2color(mean_dists,
1576+
colormap,
1577+
min_mean_dists,
1578+
max_mean_dists)
1579+
# Make sure we have arrays to speed up plotting
1580+
facecolor = np.asarray(facecolor)
1581+
ii, jj, kk = simplices.T
15701582
triangles = graph_objs.Mesh3d(x=x, y=y, z=z, facecolor=facecolor,
15711583
i=ii, j=jj, k=kk, name='')
15721584

0 commit comments

Comments
 (0)
0