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 728780a

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

File tree

1 file changed

+71
-49
lines changed

1 file changed

+71
-49
lines changed

‎plotly/tools.py‎

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,47 +3022,60 @@ 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, vmin, vmax):
30263026
"""
3027-
Normalize facecolor values by vmin/vmax and return rgb-color strings
3028-
3029-
This function takes a tuple color along with a colormap and a minimum
3030-
(vmin) and maximum (vmax) range of possible mean distances for the
3031-
given parametrized surface. It returns an rgb color based on the mean
3032-
distance between vmin and vmax
3027+
Normalize facecolors by their min/max and return rgb-color strings.
30333028
3029+
This function takes a tuple color along with a colormap.
3030+
It returns an rgb color based on the mean distance between the
3031+
minimum and maximum value of faces.
30343032
"""
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:
3033+
colormap = np.atleast_2d(colormap)
3034+
if colormap.shape[0] == 1:
30423035
# 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)
3036+
face_colors = colormap
30463037
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)))
3057-
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)
3038+
# Convert face values to between 0 and 1
3039+
vmin = faces.min()
3040+
vmax = faces.max()
3041+
if vmin >= vmax:
3042+
raise exceptions.PlotlyError("Incorrect relation between vmin"
3043+
" and vmax. The vmin value cannot"
3044+
" be bigger than or equal to the"
3045+
" value of vmax.")
3046+
# Scale t to between 0 and 1
3047+
t = (faces - vmin) / float((vmax - vmin))
3048+
t_ixs = np.round(t * 255).astype(int)
3049+
3050+
# If a list of colors is given, interpolate between them.
3051+
color_range = FigureFactory._blend_colors(colormap)
3052+
face_colors = color_range[t_ixs]
3053+
3054+
# Convert to 255 scale, and round to nearest integer
3055+
face_colors = np.round(face_colors * 255., 0)
3056+
face_colors = FigureFactory._label_rgb(face_colors)
3057+
return face_colors
30643058

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

30673080
@staticmethod
30683081
def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
@@ -3117,17 +3130,12 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
31173130
if isinstance(mean_dists[0], str):
31183131
facecolor = mean_dists
31193132
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)
3133+
# Map distances to color using the given cmap
3134+
dist_colors = FigureFactory._map_faces2color(mean_dists, colormap)
3135+
if facecolor is not None:
3136+
facecolor = np.vstack([facecolor, dist_colors])
3137+
else:
3138+
facecolor = dist_colors
31313139

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

43444361
@staticmethod
43454362
def _n_colors(lowcolor, highcolor, n_colors):
@@ -4372,7 +4389,12 @@ def _label_rgb(colors):
43724389
"""
43734390
Takes tuple (a, b, c) and returns an rgb color 'rgb(a, b, c)'
43744391
"""
4375-
return ('rgb(%s, %s, %s)' % (colors[0], colors[1], colors[2]))
4392+
if isinstance(colors, tuple):
4393+
return ('rgb(%s, %s, %s)' % (colors[0], colors[1], colors[2]))
4394+
else:
4395+
colors_label = ['rgb(%s, %s, %s)' % (r, g, b)
4396+
for r, g, b in colors]
4397+
return colors_label
43764398

43774399
@staticmethod
43784400
def _unlabel_rgb(colors):

0 commit comments

Comments
(0)

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