77
77
78
78
import decimal
79
79
from numbers import Number
80
+ import six
80
81
81
82
from plotly import exceptions
82
83
203
204
[0.8784313725490196 , '#addc30' ], [0.9411764705882353 , '#d8e219' ],
204
205
[1 , '#fde725' ]
205
206
],
206
-
207
207
'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)' ],
216
216
[0.941176 , 'rgb(243,219,79)' ], [1.000000 , 'rgb(255,233,69)' ]
217
217
]
218
-
219
218
}
220
219
221
220
@@ -245,62 +244,105 @@ def color_parser(colors, function):
245
244
return new_color_list
246
245
247
246
248
- def validate_colors (colors ):
247
+ def validate_colors (colors , colortype = 'tuple' ):
249
248
"""
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
254
250
"""
255
- colors_list = []
251
+ from numbers import Number
252
+ if colors is None :
253
+ colors = DEFAULT_PLOTLY_COLORS
256
254
257
- # if colors is a single color, put into colors_list
258
255
if isinstance (colors , str ):
259
256
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 ]]
261
263
elif 'rgb' in colors or '#' in colors :
262
- colors_list . append ( colors )
264
+ colors = [ colors ]
263
265
else :
264
266
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." )
268
269
269
270
elif isinstance (colors , tuple ):
270
271
if isinstance (colors [0 ], Number ):
271
- colors_list = [colors ]
272
+ colors = [colors ]
272
273
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 )
280
275
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 ):
283
278
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 )
287
280
for value in each_color :
288
281
if value > 255.0 :
289
282
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."
292
285
)
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 ):
298
296
for value in each_color :
299
297
if value > 1.0 :
300
298
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."
303
325
)
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
304
346
305
347
306
348
def 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,
324
366
:rtype (tuple) (colors_list, scale) if scale is None in the function call,
325
367
then scale will remain None in the returned tuple
326
368
"""
327
- #if colors_list is None:
328
369
colors_list = []
329
370
330
371
if colors is None and return_default_colors is True :
@@ -462,6 +503,22 @@ def validate_scale_values(scale):
462
503
)
463
504
464
505
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
+
465
522
def make_colorscale (colors , scale = None ):
466
523
"""
467
524
Makes a colorscale from a list of colors and a scale
0 commit comments