7777
7878import decimal
7979from numbers import Number
80+ import six
8081
8182from plotly import exceptions
8283
203204 [0.8784313725490196 , '#addc30' ], [0.9411764705882353 , '#d8e219' ],
204205 [1 , '#fde725' ]
205206 ],
206-
207207 'Cividis' : [
208- [0.000000 , 'rgb(0,32,76)' ], [0.058824 , 'rgb(0,42,102)' ],
209- [0.117647 , 'rgb(0,52,110)' ], [0.176471 , 'rgb(39,63,108)' ],
210- [0.235294 , 'rgb(60,74,107)' ], [0.294118 , 'rgb(76,85,107)' ],
211- [0.352941 , 'rgb(91,95,109)' ], [0.411765 , 'rgb(104,106,112)' ],
212- [0.470588 , 'rgb(117,117,117)' ], [0.529412 , 'rgb(131,129,120)' ],
213- [0.588235 , 'rgb(146,140,120)' ], [0.647059 , 'rgb(161,152,118)' ],
214- [0.705882 , 'rgb(176,165,114)' ], [0.764706 , 'rgb(192,177,109)' ],
215- [0.823529 , 'rgb(209,191,102)' ], [0.882353 , 'rgb(225,204,92)' ],
208+ [0.000000 , 'rgb(0,32,76)' ], [0.058824 , 'rgb(0,42,102)' ],
209+ [0.117647 , 'rgb(0,52,110)' ], [0.176471 , 'rgb(39,63,108)' ],
210+ [0.235294 , 'rgb(60,74,107)' ], [0.294118 , 'rgb(76,85,107)' ],
211+ [0.352941 , 'rgb(91,95,109)' ], [0.411765 , 'rgb(104,106,112)' ],
212+ [0.470588 , 'rgb(117,117,117)' ], [0.529412 , 'rgb(131,129,120)' ],
213+ [0.588235 , 'rgb(146,140,120)' ], [0.647059 , 'rgb(161,152,118)' ],
214+ [0.705882 , 'rgb(176,165,114)' ], [0.764706 , 'rgb(192,177,109)' ],
215+ [0.823529 , 'rgb(209,191,102)' ], [0.882353 , 'rgb(225,204,92)' ],
216216 [0.941176 , 'rgb(243,219,79)' ], [1.000000 , 'rgb(255,233,69)' ]
217217 ]
218-
219218}
220219
221220
@@ -245,62 +244,105 @@ def color_parser(colors, function):
245244 return new_color_list
246245
247246
248- def validate_colors (colors ):
247+ def validate_colors (colors , colortype = 'tuple' ):
249248 """
250- Validates color(s) and returns an error for invalid color(s)
251-
252- :param (str|tuple|list) colors: either a plotly scale name, an rgb or hex
253- color, a color tuple or a list/tuple of colors
249+ Validates color(s) and returns a list of color(s) of a specified type
254250 """
255- colors_list = []
251+ from numbers import Number
252+ if colors is None :
253+ colors = DEFAULT_PLOTLY_COLORS
256254
257- # if colors is a single color, put into colors_list
258255 if isinstance (colors , str ):
259256 if colors in PLOTLY_SCALES :
260- return
257+ colors_list = colorscale_to_colors (PLOTLY_SCALES [colors ])
258+ # TODO: fix _gantt.py/_scatter.py so that they can accept the
259+ # actual colorscale and not just a list of the first and last
260+ # color in the plotly colorscale. In resolving this issue we
261+ # will be removing the immediate line below
262+ colors = [colors_list [0 ]] + [colors_list [- 1 ]]
261263 elif 'rgb' in colors or '#' in colors :
262- colors_list . append ( colors )
264+ colors = [ colors ]
263265 else :
264266 raise exceptions .PlotlyError (
265- 'If your colors variable is a string, it must be a '
266- 'Plotly scale, an rgb color or a hex color.'
267- )
267+ "If your colors variable is a string, it must be a "
268+ "Plotly scale, an rgb color or a hex color." )
268269
269270 elif isinstance (colors , tuple ):
270271 if isinstance (colors [0 ], Number ):
271- colors_list = [colors ]
272+ colors = [colors ]
272273 else :
273- colors_list = list (colors )
274-
275- if isinstance (colors , dict ):
276- colors_list .extend (colors .values ())
277-
278- elif isinstance (colors , list ):
279- colors_list = colors
274+ colors = list (colors )
280275
281- # Validate colors in colors_list
282- for j , each_color in enumerate (colors_list ):
276+ # convert color elements in list to tuple color
277+ for j , each_color in enumerate (colors ):
283278 if 'rgb' in each_color :
284- each_color = color_parser (
285- each_color , unlabel_rgb
286- )
279+ each_color = color_parser (each_color , unlabel_rgb )
287280 for value in each_color :
288281 if value > 255.0 :
289282 raise exceptions .PlotlyError (
290- ' Whoops! The elements in your rgb colors '
291- ' tuples cannot exceed 255.0.'
283+ " Whoops! The elements in your rgb colors "
284+ " tuples cannot exceed 255.0."
292285 )
293- elif '#' in each_color :
294- each_color = color_parser (
295- each_color , hex_to_rgb
296- )
297- elif isinstance (each_color , tuple ):
286+ each_color = color_parser (each_color , unconvert_from_RGB_255 )
287+ colors [j ] = each_color
288+
289+ if '#' in each_color :
290+ each_color = color_parser (each_color , hex_to_rgb )
291+ each_color = color_parser (each_color , unconvert_from_RGB_255 )
292+
293+ colors [j ] = each_color
294+
295+ if isinstance (each_color , tuple ):
298296 for value in each_color :
299297 if value > 1.0 :
300298 raise exceptions .PlotlyError (
301- 'Whoops! The elements in your colors tuples '
302- 'cannot exceed 1.0.'
299+ "Whoops! The elements in your colors tuples "
300+ "cannot exceed 1.0."
301+ )
302+ colors [j ] = each_color
303+
304+ if colortype == 'rgb' and not isinstance (colors , six .string_types ):
305+ for j , each_color in enumerate (colors ):
306+ rgb_color = color_parser (each_color , convert_to_RGB_255 )
307+ colors [j ] = color_parser (rgb_color , label_rgb )
308+
309+ return colors
310+
311+
312+ def validate_colors_dict (colors , colortype = 'tuple' ):
313+ """
314+ Validates dictioanry of color(s)
315+ """
316+ # validate each color element in the dictionary
317+ for key in colors :
318+ if 'rgb' in colors [key ]:
319+ colors [key ] = color_parser (colors [key ], unlabel_rgb )
320+ for value in colors [key ]:
321+ if value > 255.0 :
322+ raise exceptions .PlotlyError (
323+ "Whoops! The elements in your rgb colors "
324+ "tuples cannot exceed 255.0."
303325 )
326+ colors [key ] = color_parser (colors [key ], unconvert_from_RGB_255 )
327+
328+ if '#' in colors [key ]:
329+ colors [key ] = color_parser (colors [key ], hex_to_rgb )
330+ colors [key ] = color_parser (colors [key ], unconvert_from_RGB_255 )
331+
332+ if isinstance (colors [key ], tuple ):
333+ for value in colors [key ]:
334+ if value > 1.0 :
335+ raise exceptions .PlotlyError (
336+ "Whoops! The elements in your colors tuples "
337+ "cannot exceed 1.0."
338+ )
339+
340+ if colortype == 'rgb' :
341+ for key in colors :
342+ colors [key ] = color_parser (colors [key ], convert_to_RGB_255 )
343+ colors [key ] = color_parser (colors [key ], label_rgb )
344+
345+ return colors
304346
305347
306348def convert_colors_to_same_type (colors , colortype = 'rgb' , scale = None ,
@@ -324,7 +366,6 @@ def convert_colors_to_same_type(colors, colortype='rgb', scale=None,
324366 :rtype (tuple) (colors_list, scale) if scale is None in the function call,
325367 then scale will remain None in the returned tuple
326368 """
327- #if colors_list is None:
328369 colors_list = []
329370
330371 if colors is None and return_default_colors is True :
@@ -462,6 +503,22 @@ def validate_scale_values(scale):
462503 )
463504
464505
506+ def validate_colorscale (colorscale ):
507+ """Validate the structure, scale values and colors of colorscale."""
508+ if not isinstance (colorscale , list ):
509+ # TODO Write tests for these exceptions
510+ raise exceptions .PlotlyError ("A valid colorscale must be a list." )
511+ if not all (isinstance (innerlist , list ) for innerlist in colorscale ):
512+ raise exceptions .PlotlyError (
513+ "A valid colorscale must be a list of lists."
514+ )
515+ colorscale_colors = colorscale_to_colors (colorscale )
516+ scale_values = colorscale_to_scale (colorscale )
517+
518+ validate_scale_values (scale_values )
519+ validate_colors (colorscale_colors )
520+
521+
465522def make_colorscale (colors , scale = None ):
466523 """
467524 Makes a colorscale from a list of colors and a scale
0 commit comments