Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1266151

Browse files
Creating color blending function to speed up trisurf color calculation
1 parent a1c0a9c commit 1266151

File tree

1 file changed

+67
-43
lines changed

1 file changed

+67
-43
lines changed

‎plotly/tools.py‎

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,7 +3022,7 @@ def _unconvert_from_RGB_255(colors):
30223022
return un_rgb_color
30233023

30243024
@staticmethod
3025-
def _map_face2color(face, colormap, vmin, vmax):
3025+
def _map_faces2color(faces, colormap):
30263026
"""
30273027
Normalize facecolor values by vmin/vmax and return rgb-color strings
30283028
@@ -3032,37 +3032,52 @@ def _map_face2color(face, colormap, vmin, vmax):
30323032
distance between vmin and vmax
30333033
30343034
"""
3035-
if vmin >= vmax:
3036-
raise exceptions.PlotlyError("Incorrect relation between vmin "
3037-
"and vmax. The vmin value cannot be "
3038-
"bigger than or equal to the value "
3039-
"of vmax.")
3040-
3041-
if len(colormap) == 1:
3035+
colormap = np.atleast_2d(colormap)
3036+
if colormap.shape[0] == 1:
30423037
# color each triangle face with the same color in colormap
3043-
face_color = colormap[0]
3044-
face_color = FigureFactory._convert_to_RGB_255(face_color)
3045-
face_color = FigureFactory._label_rgb(face_color)
3038+
face_colors = colormap
30463039
else:
3047-
if face == vmax:
3048-
# pick last color in colormap
3049-
face_color = colormap[-1]
3050-
face_color = FigureFactory._convert_to_RGB_255(face_color)
3051-
face_color = FigureFactory._label_rgb(face_color)
3052-
else:
3053-
# find the normalized distance t of a triangle face between
3054-
# vmin and vmax where the distance is between 0 and 1
3055-
t = (face - vmin) / float((vmax - vmin))
3056-
low_color_index = int(t / (1./(len(colormap) - 1)))
3040+
# Convert face values to between 0 and 1
3041+
vmin = faces.min()
3042+
vmax = faces.max()
3043+
if vmin >= vmax:
3044+
raise exceptions.PlotlyError("Incorrect relation between vmin"
3045+
" and vmax. The vmin value cannot"
3046+
" be bigger than or equal to the"
3047+
" value of vmax.")
3048+
# Scale t to between 0 and 1
3049+
t = (faces - vmin) / float((vmax - vmin))
3050+
t_ixs = np.round(t * 255).astype(int)
3051+
3052+
# If a list of colors is given, interpolate between them.
3053+
color_range = FigureFactory._blend_colors(colormap)
3054+
face_colors = color_range[t_ixs]
3055+
3056+
# Convert to 255 scale, and round to nearest integer
3057+
face_colors = np.round(face_colors * 255., 0)
3058+
face_colors = FigureFactory._label_rgb(face_colors)
3059+
return face_colors
30573060

3058-
face_color = FigureFactory._find_intermediate_color(
3059-
colormap[low_color_index],
3060-
colormap[low_color_index + 1],
3061-
t * (len(colormap) - 1) - low_color_index)
3062-
face_color = FigureFactory._convert_to_RGB_255(face_color)
3063-
face_color = FigureFactory._label_rgb(face_color)
3064-
3065-
return face_color
3061+
@staticmethod
3062+
def _blend_colors(colormap, n_colors=255.):
3063+
if len(colormap) == 1:
3064+
raise ValueError('Cannot blend a colormap with only one color')
3065+
# Figure out how many splits we need
3066+
n_split = np.floor(n_colors / (len(colormap) - 1)).astype(int)
3067+
n_remain = np.mod(n_colors, len(colormap))
3068+
3069+
# Iterate through pairs of colors
3070+
color_range = []
3071+
for ii in range(len(colormap) - 1):
3072+
# For each channel (r, g, b)
3073+
this_interp = []
3074+
for cstt, cstp in zip(colormap[ii], colormap[ii + 1]):
3075+
# If it's not an even split, add req'd amount on first iter
3076+
n_interp = n_split + n_remain if ii == 0 else n_split
3077+
this_interp.append(np.linspace(cstt, cstp, n_interp))
3078+
color_range.append(np.vstack(this_interp).T)
3079+
color_range = np.vstack(color_range)
3080+
return color_range
30663081

30673082
@staticmethod
30683083
def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
@@ -3117,17 +3132,12 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
31173132
if isinstance(mean_dists[0], str):
31183133
facecolor = mean_dists
31193134
else:
3120-
min_mean_dists = np.min(mean_dists)
3121-
max_mean_dists = np.max(mean_dists)
3122-
3123-
if facecolor is None:
3124-
facecolor = []
3125-
for index in range(len(mean_dists)):
3126-
color = FigureFactory._map_face2color(mean_dists[index],
3127-
colormap,
3128-
min_mean_dists,
3129-
max_mean_dists)
3130-
facecolor.append(color)
3135+
# Map distances to color using the given cmap
3136+
dist_colors = FigureFactory._map_faces2color(mean_dists, colormap)
3137+
if facecolor is not None:
3138+
facecolor = np.vstack([facecolor, dist_colors])
3139+
else:
3140+
facecolor = dist_colors
31313141

31323142
# Make sure we have arrays to speed up plotting
31333143
facecolor = np.asarray(facecolor)
@@ -4338,8 +4348,17 @@ def _convert_to_RGB_255(colors):
43384348
"""
43394349
Multiplies each element of a triplet by 255
43404350
"""
4341-
4342-
return (colors[0]*255.0, colors[1]*255.0, colors[2]*255.0)
4351+
if isinstance(colors, tuple):
4352+
return (colors[0]*255.0, colors[1]*255.0, colors[2]*255.0)
4353+
elif isinstance(colors, np.ndarray):
4354+
# Vectorize the multiplication and return a list of tuples
4355+
return [tuple(ii) for ii in colors * 255.0]
4356+
else:
4357+
colors_255 = []
4358+
for color in colors:
4359+
rgb_color = (color[0]*255.0, color[1]*255.0, color[2]*255.0)
4360+
colors_255.append(rgb_color)
4361+
return colors_255
43434362

43444363
@staticmethod
43454364
def _n_colors(lowcolor, highcolor, n_colors):
@@ -4372,7 +4391,12 @@ def _label_rgb(colors):
43724391
"""
43734392
Takes tuple (a, b, c) and returns an rgb color 'rgb(a, b, c)'
43744393
"""
4375-
return ('rgb(%s, %s, %s)' % (colors[0], colors[1], colors[2]))
4394+
if isinstance(colors, tuple):
4395+
return ('rgb(%s, %s, %s)' % (colors[0], colors[1], colors[2]))
4396+
else:
4397+
colors_label = ['rgb(%s, %s, %s)' % (r, g, b)
4398+
for r, g, b in colors]
4399+
return colors_label
43764400

43774401
@staticmethod
43784402
def _unlabel_rgb(colors):

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /