@@ -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