@@ -3227,47 +3227,60 @@ def _unconvert_from_RGB_255(colors):
3227
3227
return un_rgb_color
3228
3228
3229
3229
@staticmethod
3230
- def _map_face2color ( face , colormap , vmin , vmax ):
3230
+ def _map_faces2color ( faces , colormap ):
3231
3231
"""
3232
- Normalize facecolor values by vmin/vmax and return rgb-color strings
3233
-
3234
- This function takes a tuple color along with a colormap and a minimum
3235
- (vmin) and maximum (vmax) range of possible mean distances for the
3236
- given parametrized surface. It returns an rgb color based on the mean
3237
- distance between vmin and vmax
3232
+ Normalize facecolors by their min/max and return rgb-color strings.
3238
3233
3234
+ This function takes a tuple color along with a colormap.
3235
+ It returns an rgb color based on the mean distance between the
3236
+ minimum and maximum value of faces.
3239
3237
"""
3240
- if vmin >= vmax :
3241
- raise exceptions .PlotlyError ("Incorrect relation between vmin "
3242
- "and vmax. The vmin value cannot be "
3243
- "bigger than or equal to the value "
3244
- "of vmax." )
3245
-
3246
- if len (colormap ) == 1 :
3238
+ colormap = np .atleast_2d (colormap )
3239
+ if colormap .shape [0 ] == 1 :
3247
3240
# color each triangle face with the same color in colormap
3248
- face_color = colormap [0 ]
3249
- face_color = FigureFactory ._convert_to_RGB_255 (face_color )
3250
- face_color = FigureFactory ._label_rgb (face_color )
3241
+ face_colors = colormap
3251
3242
else :
3252
- if face == vmax :
3253
- # pick last color in colormap
3254
- face_color = colormap [- 1 ]
3255
- face_color = FigureFactory ._convert_to_RGB_255 (face_color )
3256
- face_color = FigureFactory ._label_rgb (face_color )
3257
- else :
3258
- # find the normalized distance t of a triangle face between
3259
- # vmin and vmax where the distance is between 0 and 1
3260
- t = (face - vmin ) / float ((vmax - vmin ))
3261
- low_color_index = int (t / (1. / (len (colormap ) - 1 )))
3262
-
3263
- face_color = FigureFactory ._find_intermediate_color (
3264
- colormap [low_color_index ],
3265
- colormap [low_color_index + 1 ],
3266
- t * (len (colormap ) - 1 ) - low_color_index )
3267
- face_color = FigureFactory ._convert_to_RGB_255 (face_color )
3268
- face_color = FigureFactory ._label_rgb (face_color )
3243
+ # Convert face values to between 0 and 1
3244
+ vmin = faces .min ()
3245
+ vmax = faces .max ()
3246
+ if vmin >= vmax :
3247
+ raise exceptions .PlotlyError ("Incorrect relation between vmin"
3248
+ " and vmax. The vmin value cannot"
3249
+ " be bigger than or equal to the"
3250
+ " value of vmax." )
3251
+ # Scale t to between 0 and 1
3252
+ t = (faces - vmin ) / float ((vmax - vmin ))
3253
+ t_ixs = np .round (t * 255 ).astype (int )
3254
+
3255
+ # If a list of colors is given, interpolate between them.
3256
+ color_range = FigureFactory ._blend_colors (colormap )
3257
+ face_colors = color_range [t_ixs ]
3258
+
3259
+ # Convert to 255 scale, and round to nearest integer
3260
+ face_colors = np .round (face_colors * 255. , 0 )
3261
+ face_colors = FigureFactory ._label_rgb (face_colors )
3262
+ return face_colors
3269
3263
3270
- return face_color
3264
+ @staticmethod
3265
+ def _blend_colors (colormap , n_colors = 255. ):
3266
+ if len (colormap ) == 1 :
3267
+ raise ValueError ('Cannot blend a colormap with only one color' )
3268
+ # Figure out how many splits we need
3269
+ n_split = np .floor (n_colors / (len (colormap ) - 1 )).astype (int )
3270
+ n_remain = np .mod (n_colors , len (colormap ))
3271
+
3272
+ # Iterate through pairs of colors
3273
+ color_range = []
3274
+ for ii in range (len (colormap ) - 1 ):
3275
+ # For each channel (r, g, b)
3276
+ this_interp = []
3277
+ for cstt , cstp in zip (colormap [ii ], colormap [ii + 1 ]):
3278
+ # If it's not an even split, add req'd amount on first iter
3279
+ n_interp = n_split + n_remain if ii == 0 else n_split
3280
+ this_interp .append (np .linspace (cstt , cstp , n_interp ))
3281
+ color_range .append (np .vstack (this_interp ).T )
3282
+ color_range = np .vstack (color_range )
3283
+ return color_range
3271
3284
3272
3285
@staticmethod
3273
3286
def _trisurf (x , y , z , simplices , show_colorbar , colormap = None ,
@@ -3322,17 +3335,12 @@ def _trisurf(x, y, z, simplices, show_colorbar, colormap=None,
3322
3335
if isinstance (mean_dists [0 ], str ):
3323
3336
facecolor = mean_dists
3324
3337
else :
3325
- min_mean_dists = np .min (mean_dists )
3326
- max_mean_dists = np .max (mean_dists )
3327
-
3328
- if facecolor is None :
3329
- facecolor = []
3330
- for index in range (len (mean_dists )):
3331
- color = FigureFactory ._map_face2color (mean_dists [index ],
3332
- colormap ,
3333
- min_mean_dists ,
3334
- max_mean_dists )
3335
- facecolor .append (color )
3338
+ # Map distances to color using the given cmap
3339
+ dist_colors = FigureFactory ._map_faces2color (mean_dists , colormap )
3340
+ if facecolor is not None :
3341
+ facecolor = np .vstack ([facecolor , dist_colors ])
3342
+ else :
3343
+ facecolor = dist_colors
3336
3344
3337
3345
# Make sure we have arrays to speed up plotting
3338
3346
facecolor = np .asarray (facecolor )
@@ -4564,8 +4572,17 @@ def _convert_to_RGB_255(colors):
4564
4572
"""
4565
4573
Multiplies each element of a triplet by 255
4566
4574
"""
4567
-
4568
- return (colors [0 ]* 255.0 , colors [1 ]* 255.0 , colors [2 ]* 255.0 )
4575
+ if isinstance (colors , tuple ):
4576
+ return (colors [0 ]* 255.0 , colors [1 ]* 255.0 , colors [2 ]* 255.0 )
4577
+ elif isinstance (colors , np .ndarray ):
4578
+ # Vectorize the multiplication and return a list of tuples
4579
+ return [tuple (ii ) for ii in colors * 255.0 ]
4580
+ else :
4581
+ colors_255 = []
4582
+ for color in colors :
4583
+ rgb_color = (color [0 ]* 255.0 , color [1 ]* 255.0 , color [2 ]* 255.0 )
4584
+ colors_255 .append (rgb_color )
4585
+ return colors_255
4569
4586
4570
4587
@staticmethod
4571
4588
def _n_colors (lowcolor , highcolor , n_colors ):
@@ -4598,7 +4615,12 @@ def _label_rgb(colors):
4598
4615
"""
4599
4616
Takes tuple (a, b, c) and returns an rgb color 'rgb(a, b, c)'
4600
4617
"""
4601
- return ('rgb(%s, %s, %s)' % (colors [0 ], colors [1 ], colors [2 ]))
4618
+ if isinstance (colors , tuple ):
4619
+ return ('rgb(%s, %s, %s)' % (colors [0 ], colors [1 ], colors [2 ]))
4620
+ else :
4621
+ colors_label = ['rgb(%s, %s, %s)' % (r , g , b )
4622
+ for r , g , b in colors ]
4623
+ return colors_label
4602
4624
4603
4625
@staticmethod
4604
4626
def _unlabel_rgb (colors ):
0 commit comments