Skip to content

No colors functions in ff utils #1301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 102 additions & 45 deletions plotly/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@

import decimal
from numbers import Number
import six

from plotly import exceptions

Expand Down Expand Up @@ -203,19 +204,17 @@
[0.8784313725490196, '#addc30'], [0.9411764705882353, '#d8e219'],
[1, '#fde725']
],

'Cividis': [
[0.000000, 'rgb(0,32,76)'], [0.058824, 'rgb(0,42,102)'],
[0.117647, 'rgb(0,52,110)'], [0.176471, 'rgb(39,63,108)'],
[0.235294, 'rgb(60,74,107)'], [0.294118, 'rgb(76,85,107)'],
[0.352941, 'rgb(91,95,109)'], [0.411765, 'rgb(104,106,112)'],
[0.470588, 'rgb(117,117,117)'], [0.529412, 'rgb(131,129,120)'],
[0.588235, 'rgb(146,140,120)'], [0.647059, 'rgb(161,152,118)'],
[0.705882, 'rgb(176,165,114)'], [0.764706, 'rgb(192,177,109)'],
[0.823529, 'rgb(209,191,102)'], [0.882353, 'rgb(225,204,92)'],
[0.000000, 'rgb(0,32,76)'], [0.058824, 'rgb(0,42,102)'],
[0.117647, 'rgb(0,52,110)'], [0.176471, 'rgb(39,63,108)'],
[0.235294, 'rgb(60,74,107)'], [0.294118, 'rgb(76,85,107)'],
[0.352941, 'rgb(91,95,109)'], [0.411765, 'rgb(104,106,112)'],
[0.470588, 'rgb(117,117,117)'], [0.529412, 'rgb(131,129,120)'],
[0.588235, 'rgb(146,140,120)'], [0.647059, 'rgb(161,152,118)'],
[0.705882, 'rgb(176,165,114)'], [0.764706, 'rgb(192,177,109)'],
[0.823529, 'rgb(209,191,102)'], [0.882353, 'rgb(225,204,92)'],
[0.941176, 'rgb(243,219,79)'], [1.000000, 'rgb(255,233,69)']
]

}


Expand Down Expand Up @@ -245,62 +244,105 @@ def color_parser(colors, function):
return new_color_list


def validate_colors(colors):
def validate_colors(colors, colortype='tuple'):
"""
Validates color(s) and returns an error for invalid color(s)

:param (str|tuple|list) colors: either a plotly scale name, an rgb or hex
color, a color tuple or a list/tuple of colors
Validates color(s) and returns a list of color(s) of a specified type
"""
colors_list = []
from numbers import Number
if colors is None:
colors = DEFAULT_PLOTLY_COLORS

# if colors is a single color, put into colors_list
if isinstance(colors, str):
if colors in PLOTLY_SCALES:
return
colors_list = colorscale_to_colors(PLOTLY_SCALES[colors])
# TODO: fix _gantt.py/_scatter.py so that they can accept the
# actual colorscale and not just a list of the first and last
# color in the plotly colorscale. In resolving this issue we
# will be removing the immediate line below
colors = [colors_list[0]] + [colors_list[-1]]
elif 'rgb' in colors or '#' in colors:
colors_list.append(colors)
colors = [colors]
else:
raise exceptions.PlotlyError(
'If your colors variable is a string, it must be a '
'Plotly scale, an rgb color or a hex color.'
)
"If your colors variable is a string, it must be a "
"Plotly scale, an rgb color or a hex color.")

elif isinstance(colors, tuple):
if isinstance(colors[0], Number):
colors_list = [colors]
colors = [colors]
else:
colors_list = list(colors)

if isinstance(colors, dict):
colors_list.extend(colors.values())

elif isinstance(colors, list):
colors_list = colors
colors = list(colors)

# Validate colors in colors_list
for j, each_color in enumerate(colors_list):
# convert color elements in list to tuple color
for j, each_color in enumerate(colors):
if 'rgb' in each_color:
each_color = color_parser(
each_color, unlabel_rgb
)
each_color = color_parser(each_color, unlabel_rgb)
for value in each_color:
if value > 255.0:
raise exceptions.PlotlyError(
'Whoops! The elements in your rgb colors '
'tuples cannot exceed 255.0.'
"Whoops! The elements in your rgb colors "
"tuples cannot exceed 255.0."
)
elif '#' in each_color:
each_color = color_parser(
each_color, hex_to_rgb
)
elif isinstance(each_color, tuple):
each_color = color_parser(each_color, unconvert_from_RGB_255)
colors[j] = each_color

if '#' in each_color:
each_color = color_parser(each_color, hex_to_rgb)
each_color = color_parser(each_color, unconvert_from_RGB_255)

colors[j] = each_color

if isinstance(each_color, tuple):
for value in each_color:
if value > 1.0:
raise exceptions.PlotlyError(
'Whoops! The elements in your colors tuples '
'cannot exceed 1.0.'
"Whoops! The elements in your colors tuples "
"cannot exceed 1.0."
)
colors[j] = each_color

if colortype == 'rgb' and not isinstance(colors, six.string_types):
for j, each_color in enumerate(colors):
rgb_color = color_parser(each_color, convert_to_RGB_255)
colors[j] = color_parser(rgb_color, label_rgb)

return colors


def validate_colors_dict(colors, colortype='tuple'):
"""
Validates dictioanry of color(s)
"""
# validate each color element in the dictionary
for key in colors:
if 'rgb' in colors[key]:
colors[key] = color_parser(colors[key], unlabel_rgb)
for value in colors[key]:
if value > 255.0:
raise exceptions.PlotlyError(
"Whoops! The elements in your rgb colors "
"tuples cannot exceed 255.0."
)
colors[key] = color_parser(colors[key], unconvert_from_RGB_255)

if '#' in colors[key]:
colors[key] = color_parser(colors[key], hex_to_rgb)
colors[key] = color_parser(colors[key], unconvert_from_RGB_255)

if isinstance(colors[key], tuple):
for value in colors[key]:
if value > 1.0:
raise exceptions.PlotlyError(
"Whoops! The elements in your colors tuples "
"cannot exceed 1.0."
)

if colortype == 'rgb':
for key in colors:
colors[key] = color_parser(colors[key], convert_to_RGB_255)
colors[key] = color_parser(colors[key], label_rgb)

return colors


def convert_colors_to_same_type(colors, colortype='rgb', scale=None,
Expand All @@ -324,7 +366,6 @@ def convert_colors_to_same_type(colors, colortype='rgb', scale=None,
:rtype (tuple) (colors_list, scale) if scale is None in the function call,
then scale will remain None in the returned tuple
"""
#if colors_list is None:
colors_list = []

if colors is None and return_default_colors is True:
Expand Down Expand Up @@ -462,6 +503,22 @@ def validate_scale_values(scale):
)


def validate_colorscale(colorscale):
"""Validate the structure, scale values and colors of colorscale."""
if not isinstance(colorscale, list):
# TODO Write tests for these exceptions
raise exceptions.PlotlyError("A valid colorscale must be a list.")
if not all(isinstance(innerlist, list) for innerlist in colorscale):
raise exceptions.PlotlyError(
"A valid colorscale must be a list of lists."
)
colorscale_colors = colorscale_to_colors(colorscale)
scale_values = colorscale_to_scale(colorscale)

validate_scale_values(scale_values)
validate_colors(colorscale_colors)


def make_colorscale(colors, scale=None):
"""
Makes a colorscale from a list of colors and a scale
Expand Down
7 changes: 4 additions & 3 deletions plotly/figure_factory/_2d_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from numbers import Number

from plotly import exceptions
import plotly.colors as clrs
from plotly.figure_factory import utils
from plotly.graph_objs import graph_objs

Expand Down Expand Up @@ -100,12 +101,12 @@ def create_2d_density(x, y, colorscale='Earth', ncontours=20,
"Both lists 'x' and 'y' must be the same length."
)

colorscale = utils.validate_colors(colorscale, 'rgb')
colorscale = clrs.validate_colors(colorscale, 'rgb')
colorscale = make_linear_colorscale(colorscale)

# validate hist_color and point_color
hist_color = utils.validate_colors(hist_color, 'rgb')
point_color = utils.validate_colors(point_color, 'rgb')
hist_color = clrs.validate_colors(hist_color, 'rgb')
point_color = clrs.validate_colors(point_color, 'rgb')

trace1 = graph_objs.Scatter(
x=x, y=y, mode='markers', name='points',
Expand Down
3 changes: 2 additions & 1 deletion plotly/figure_factory/_annotated_heatmap.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import

from plotly import exceptions, optional_imports
import plotly.colors as clrs
from plotly.figure_factory import utils
from plotly.graph_objs import graph_objs
from plotly.validators.heatmap import ColorscaleValidator
Expand Down Expand Up @@ -123,7 +124,7 @@ def to_rgb_color_list(color_str, default):
if 'rgb' in color_str:
return [int(v) for v in color_str.strip('rgb()').split(',')]
elif '#' in color_str:
return utils.hex_to_rgb(color_str)
return clrs.hex_to_rgb(color_str)
else:
return default

Expand Down
21 changes: 8 additions & 13 deletions plotly/figure_factory/_bullet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import collections
import math

from plotly import colors, exceptions, optional_imports
from plotly import exceptions, optional_imports
import plotly.colors as clrs
from plotly.figure_factory import utils

import plotly
Expand All @@ -12,15 +13,9 @@
pd = optional_imports.get_module('pandas')


def is_sequence(obj):
return (isinstance(obj, collections.Sequence) and
not isinstance(obj, str))


def _bullet(df, markers, measures, ranges, subtitles, titles, orientation,
range_colors, measure_colors, horizontal_spacing,
vertical_spacing, scatter_options, layout_options):

num_of_lanes = len(df)
num_of_rows = num_of_lanes if orientation == 'h' else 1
num_of_cols = 1 if orientation == 'h' else num_of_lanes
Expand Down Expand Up @@ -78,7 +73,7 @@ def _bullet(df, markers, measures, ranges, subtitles, titles, orientation,
for row in range(num_of_lanes):
# ranges bars
for idx in range(len(df.iloc[row]['ranges'])):
inter_colors = colors.n_colors(
inter_colors = clrs.n_colors(
range_colors[0], range_colors[1],
len(df.iloc[row]['ranges']), 'rgb'
)
Expand All @@ -104,7 +99,7 @@ def _bullet(df, markers, measures, ranges, subtitles, titles, orientation,

# measures bars
for idx in range(len(df.iloc[row]['measures'])):
inter_colors = colors.n_colors(
inter_colors = clrs.n_colors(
measure_colors[0], measure_colors[1],
len(df.iloc[row]['measures']), 'rgb'
)
Expand Down Expand Up @@ -261,7 +256,7 @@ def create_bullet(data, markers=None, measures=None, ranges=None,
"'pandas' must be installed for this figure factory."
)

if is_sequence(data):
if utils.is_sequence(data):
if not all(isinstance(item, dict) for item in data):
raise exceptions.PlotlyError(
'Every entry of the data argument list, tuple, etc must '
Expand All @@ -275,7 +270,7 @@ def create_bullet(data, markers=None, measures=None, ranges=None,

# make DataFrame from data with correct column headers
col_names = ['titles', 'subtitle', 'markers', 'measures', 'ranges']
if is_sequence(data):
if utils.is_sequence(data):
df = pd.DataFrame(
[
[d[titles] for d in data] if titles else [''] * len(data),
Expand Down Expand Up @@ -317,8 +312,8 @@ def create_bullet(data, markers=None, measures=None, ranges=None,
"Both 'range_colors' or 'measure_colors' must be a list "
"of two valid colors."
)
colors.validate_colors(colors_list)
colors_list = colors.convert_colors_to_same_type(colors_list,
clrs.validate_colors(colors_list)
colors_list = clrs.convert_colors_to_same_type(colors_list,
'rgb')[0]

# default scatter options
Expand Down
25 changes: 13 additions & 12 deletions plotly/figure_factory/_county_choropleth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from plotly import colors, exceptions, optional_imports
from plotly import exceptions, optional_imports
import plotly.colors as clrs

from plotly.figure_factory import utils

Expand Down Expand Up @@ -641,14 +642,14 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None,

if not colorscale:
colorscale = []
viridis_colors = colors.colorscale_to_colors(
colors.PLOTLY_SCALES['Viridis']
viridis_colors = clrs.colorscale_to_colors(
clrs.PLOTLY_SCALES['Viridis']
)
viridis_colors = colors.color_parser(
viridis_colors, colors.hex_to_rgb
viridis_colors = clrs.color_parser(
viridis_colors, clrs.hex_to_rgb
)
viridis_colors = colors.color_parser(
viridis_colors, colors.label_rgb
viridis_colors = clrs.color_parser(
viridis_colors, clrs.label_rgb
)
viri_len = len(viridis_colors) + 1
viri_intervals = utils.endpts_to_intervals(
Expand All @@ -665,18 +666,18 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None,
intermed = ((L - viri_intervals[idx][0]) /
(viri_intervals[idx][1] - viri_intervals[idx][0]))

float_color = colors.find_intermediate_color(
float_color = clrs.find_intermediate_color(
viridis_colors[idx],
viridis_colors[idx],
intermed,
colortype='rgb'
)

# make R,G,B into int values
float_color = colors.unlabel_rgb(float_color)
float_color = colors.unconvert_from_RGB_255(float_color)
int_rgb = colors.convert_to_RGB_255(float_color)
int_rgb = colors.label_rgb(int_rgb)
float_color = clrs.unlabel_rgb(float_color)
float_color = clrs.unconvert_from_RGB_255(float_color)
int_rgb = clrs.convert_to_RGB_255(float_color)
int_rgb = clrs.label_rgb(int_rgb)

colorscale.append(int_rgb)

Expand Down
Loading