done
This commit is contained in:
2711
lib/python3.11/site-packages/_plotly_utils/basevalidators.py
Normal file
2711
lib/python3.11/site-packages/_plotly_utils/basevalidators.py
Normal file
File diff suppressed because it is too large
Load Diff
883
lib/python3.11/site-packages/_plotly_utils/colors/__init__.py
Normal file
883
lib/python3.11/site-packages/_plotly_utils/colors/__init__.py
Normal file
@ -0,0 +1,883 @@
|
||||
"""
|
||||
colors
|
||||
=====
|
||||
|
||||
Functions that manipulate colors and arrays of colors.
|
||||
|
||||
-----
|
||||
There are three basic types of color types: rgb, hex and tuple:
|
||||
|
||||
rgb - An rgb color is a string of the form 'rgb(a,b,c)' where a, b and c are
|
||||
integers between 0 and 255 inclusive.
|
||||
|
||||
hex - A hex color is a string of the form '#xxxxxx' where each x is a
|
||||
character that belongs to the set [0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f]. This is
|
||||
just the set of characters used in the hexadecimal numeric system.
|
||||
|
||||
tuple - A tuple color is a 3-tuple of the form (a,b,c) where a, b and c are
|
||||
floats between 0 and 1 inclusive.
|
||||
|
||||
-----
|
||||
Colormaps and Colorscales:
|
||||
A colormap or a colorscale is a correspondence between values - Pythonic
|
||||
objects such as strings and floats - to colors.
|
||||
|
||||
There are typically two main types of colormaps that exist: numerical and
|
||||
categorical colormaps.
|
||||
|
||||
Numerical:
|
||||
----------
|
||||
Numerical colormaps are used when the coloring column being used takes a
|
||||
spectrum of values or numbers.
|
||||
|
||||
A classic example from the Plotly library:
|
||||
```
|
||||
rainbow_colorscale = [
|
||||
[0, 'rgb(150,0,90)'], [0.125, 'rgb(0,0,200)'],
|
||||
[0.25, 'rgb(0,25,255)'], [0.375, 'rgb(0,152,255)'],
|
||||
[0.5, 'rgb(44,255,150)'], [0.625, 'rgb(151,255,0)'],
|
||||
[0.75, 'rgb(255,234,0)'], [0.875, 'rgb(255,111,0)'],
|
||||
[1, 'rgb(255,0,0)']
|
||||
]
|
||||
```
|
||||
|
||||
Notice that this colorscale is a list of lists with each inner list containing
|
||||
a number and a color. These left hand numbers in the nested lists go from 0 to
|
||||
1, and they are like pointers tell you when a number is mapped to a specific
|
||||
color.
|
||||
|
||||
If you have a column of numbers `col_num` that you want to plot, and you know
|
||||
|
||||
```
|
||||
min(col_num) = 0
|
||||
max(col_num) = 100
|
||||
```
|
||||
|
||||
then if you pull out the number `12.5` in the list and want to figure out what
|
||||
color the corresponding chart element (bar, scatter plot, etc) is going to be,
|
||||
you'll figure out that proportionally 12.5 to 100 is the same as 0.125 to 1.
|
||||
So, the point will be mapped to 'rgb(0,0,200)'.
|
||||
|
||||
All other colors between the pinned values in a colorscale are linearly
|
||||
interpolated.
|
||||
|
||||
Categorical:
|
||||
------------
|
||||
Alternatively, a categorical colormap is used to assign a specific value in a
|
||||
color column to a specific color everytime it appears in the dataset.
|
||||
|
||||
A column of strings in a panadas.dataframe that is chosen to serve as the
|
||||
color index would naturally use a categorical colormap. However, you can
|
||||
choose to use a categorical colormap with a column of numbers.
|
||||
|
||||
Be careful! If you have a lot of unique numbers in your color column you will
|
||||
end up with a colormap that is massive and may slow down graphing performance.
|
||||
"""
|
||||
|
||||
import decimal
|
||||
from numbers import Number
|
||||
|
||||
from _plotly_utils import exceptions
|
||||
|
||||
|
||||
# Built-in qualitative color sequences and sequential,
|
||||
# diverging and cyclical color scales.
|
||||
#
|
||||
# Initially ported over from plotly_express
|
||||
from . import ( # noqa: F401
|
||||
qualitative,
|
||||
sequential,
|
||||
diverging,
|
||||
cyclical,
|
||||
cmocean,
|
||||
colorbrewer,
|
||||
carto,
|
||||
plotlyjs,
|
||||
)
|
||||
|
||||
DEFAULT_PLOTLY_COLORS = [
|
||||
"rgb(31, 119, 180)",
|
||||
"rgb(255, 127, 14)",
|
||||
"rgb(44, 160, 44)",
|
||||
"rgb(214, 39, 40)",
|
||||
"rgb(148, 103, 189)",
|
||||
"rgb(140, 86, 75)",
|
||||
"rgb(227, 119, 194)",
|
||||
"rgb(127, 127, 127)",
|
||||
"rgb(188, 189, 34)",
|
||||
"rgb(23, 190, 207)",
|
||||
]
|
||||
|
||||
PLOTLY_SCALES = {
|
||||
"Greys": [[0, "rgb(0,0,0)"], [1, "rgb(255,255,255)"]],
|
||||
"YlGnBu": [
|
||||
[0, "rgb(8,29,88)"],
|
||||
[0.125, "rgb(37,52,148)"],
|
||||
[0.25, "rgb(34,94,168)"],
|
||||
[0.375, "rgb(29,145,192)"],
|
||||
[0.5, "rgb(65,182,196)"],
|
||||
[0.625, "rgb(127,205,187)"],
|
||||
[0.75, "rgb(199,233,180)"],
|
||||
[0.875, "rgb(237,248,217)"],
|
||||
[1, "rgb(255,255,217)"],
|
||||
],
|
||||
"Greens": [
|
||||
[0, "rgb(0,68,27)"],
|
||||
[0.125, "rgb(0,109,44)"],
|
||||
[0.25, "rgb(35,139,69)"],
|
||||
[0.375, "rgb(65,171,93)"],
|
||||
[0.5, "rgb(116,196,118)"],
|
||||
[0.625, "rgb(161,217,155)"],
|
||||
[0.75, "rgb(199,233,192)"],
|
||||
[0.875, "rgb(229,245,224)"],
|
||||
[1, "rgb(247,252,245)"],
|
||||
],
|
||||
"YlOrRd": [
|
||||
[0, "rgb(128,0,38)"],
|
||||
[0.125, "rgb(189,0,38)"],
|
||||
[0.25, "rgb(227,26,28)"],
|
||||
[0.375, "rgb(252,78,42)"],
|
||||
[0.5, "rgb(253,141,60)"],
|
||||
[0.625, "rgb(254,178,76)"],
|
||||
[0.75, "rgb(254,217,118)"],
|
||||
[0.875, "rgb(255,237,160)"],
|
||||
[1, "rgb(255,255,204)"],
|
||||
],
|
||||
"Bluered": [[0, "rgb(0,0,255)"], [1, "rgb(255,0,0)"]],
|
||||
# modified RdBu based on
|
||||
# www.sandia.gov/~kmorel/documents/ColorMaps/ColorMapsExpanded.pdf
|
||||
"RdBu": [
|
||||
[0, "rgb(5,10,172)"],
|
||||
[0.35, "rgb(106,137,247)"],
|
||||
[0.5, "rgb(190,190,190)"],
|
||||
[0.6, "rgb(220,170,132)"],
|
||||
[0.7, "rgb(230,145,90)"],
|
||||
[1, "rgb(178,10,28)"],
|
||||
],
|
||||
# Scale for non-negative numeric values
|
||||
"Reds": [
|
||||
[0, "rgb(220,220,220)"],
|
||||
[0.2, "rgb(245,195,157)"],
|
||||
[0.4, "rgb(245,160,105)"],
|
||||
[1, "rgb(178,10,28)"],
|
||||
],
|
||||
# Scale for non-positive numeric values
|
||||
"Blues": [
|
||||
[0, "rgb(5,10,172)"],
|
||||
[0.35, "rgb(40,60,190)"],
|
||||
[0.5, "rgb(70,100,245)"],
|
||||
[0.6, "rgb(90,120,245)"],
|
||||
[0.7, "rgb(106,137,247)"],
|
||||
[1, "rgb(220,220,220)"],
|
||||
],
|
||||
"Picnic": [
|
||||
[0, "rgb(0,0,255)"],
|
||||
[0.1, "rgb(51,153,255)"],
|
||||
[0.2, "rgb(102,204,255)"],
|
||||
[0.3, "rgb(153,204,255)"],
|
||||
[0.4, "rgb(204,204,255)"],
|
||||
[0.5, "rgb(255,255,255)"],
|
||||
[0.6, "rgb(255,204,255)"],
|
||||
[0.7, "rgb(255,153,255)"],
|
||||
[0.8, "rgb(255,102,204)"],
|
||||
[0.9, "rgb(255,102,102)"],
|
||||
[1, "rgb(255,0,0)"],
|
||||
],
|
||||
"Rainbow": [
|
||||
[0, "rgb(150,0,90)"],
|
||||
[0.125, "rgb(0,0,200)"],
|
||||
[0.25, "rgb(0,25,255)"],
|
||||
[0.375, "rgb(0,152,255)"],
|
||||
[0.5, "rgb(44,255,150)"],
|
||||
[0.625, "rgb(151,255,0)"],
|
||||
[0.75, "rgb(255,234,0)"],
|
||||
[0.875, "rgb(255,111,0)"],
|
||||
[1, "rgb(255,0,0)"],
|
||||
],
|
||||
"Portland": [
|
||||
[0, "rgb(12,51,131)"],
|
||||
[0.25, "rgb(10,136,186)"],
|
||||
[0.5, "rgb(242,211,56)"],
|
||||
[0.75, "rgb(242,143,56)"],
|
||||
[1, "rgb(217,30,30)"],
|
||||
],
|
||||
"Jet": [
|
||||
[0, "rgb(0,0,131)"],
|
||||
[0.125, "rgb(0,60,170)"],
|
||||
[0.375, "rgb(5,255,255)"],
|
||||
[0.625, "rgb(255,255,0)"],
|
||||
[0.875, "rgb(250,0,0)"],
|
||||
[1, "rgb(128,0,0)"],
|
||||
],
|
||||
"Hot": [
|
||||
[0, "rgb(0,0,0)"],
|
||||
[0.3, "rgb(230,0,0)"],
|
||||
[0.6, "rgb(255,210,0)"],
|
||||
[1, "rgb(255,255,255)"],
|
||||
],
|
||||
"Blackbody": [
|
||||
[0, "rgb(0,0,0)"],
|
||||
[0.2, "rgb(230,0,0)"],
|
||||
[0.4, "rgb(230,210,0)"],
|
||||
[0.7, "rgb(255,255,255)"],
|
||||
[1, "rgb(160,200,255)"],
|
||||
],
|
||||
"Earth": [
|
||||
[0, "rgb(0,0,130)"],
|
||||
[0.1, "rgb(0,180,180)"],
|
||||
[0.2, "rgb(40,210,40)"],
|
||||
[0.4, "rgb(230,230,50)"],
|
||||
[0.6, "rgb(120,70,20)"],
|
||||
[1, "rgb(255,255,255)"],
|
||||
],
|
||||
"Electric": [
|
||||
[0, "rgb(0,0,0)"],
|
||||
[0.15, "rgb(30,0,100)"],
|
||||
[0.4, "rgb(120,0,100)"],
|
||||
[0.6, "rgb(160,90,0)"],
|
||||
[0.8, "rgb(230,200,0)"],
|
||||
[1, "rgb(255,250,220)"],
|
||||
],
|
||||
"Viridis": [
|
||||
[0, "#440154"],
|
||||
[0.06274509803921569, "#48186a"],
|
||||
[0.12549019607843137, "#472d7b"],
|
||||
[0.18823529411764706, "#424086"],
|
||||
[0.25098039215686274, "#3b528b"],
|
||||
[0.3137254901960784, "#33638d"],
|
||||
[0.3764705882352941, "#2c728e"],
|
||||
[0.4392156862745098, "#26828e"],
|
||||
[0.5019607843137255, "#21918c"],
|
||||
[0.5647058823529412, "#1fa088"],
|
||||
[0.6274509803921569, "#28ae80"],
|
||||
[0.6901960784313725, "#3fbc73"],
|
||||
[0.7529411764705882, "#5ec962"],
|
||||
[0.8156862745098039, "#84d44b"],
|
||||
[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.941176, "rgb(243,219,79)"],
|
||||
[1.000000, "rgb(255,233,69)"],
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def color_parser(colors, function):
|
||||
"""
|
||||
Takes color(s) and a function and applies the function on the color(s)
|
||||
|
||||
In particular, this function identifies whether the given color object
|
||||
is an iterable or not and applies the given color-parsing function to
|
||||
the color or iterable of colors. If given an iterable, it will only be
|
||||
able to work with it if all items in the iterable are of the same type
|
||||
- rgb string, hex string or tuple
|
||||
"""
|
||||
if isinstance(colors, str):
|
||||
return function(colors)
|
||||
|
||||
if isinstance(colors, tuple) and isinstance(colors[0], Number):
|
||||
return function(colors)
|
||||
|
||||
if hasattr(colors, "__iter__"):
|
||||
if isinstance(colors, tuple):
|
||||
new_color_tuple = tuple(function(item) for item in colors)
|
||||
return new_color_tuple
|
||||
|
||||
else:
|
||||
new_color_list = [function(item) for item in colors]
|
||||
return new_color_list
|
||||
|
||||
|
||||
def validate_colors(colors, colortype="tuple"):
|
||||
"""
|
||||
Validates color(s) and returns a list of color(s) of a specified type
|
||||
"""
|
||||
from numbers import Number
|
||||
|
||||
if colors is None:
|
||||
colors = DEFAULT_PLOTLY_COLORS
|
||||
|
||||
if isinstance(colors, str):
|
||||
if colors in PLOTLY_SCALES:
|
||||
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 = [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."
|
||||
)
|
||||
|
||||
elif isinstance(colors, tuple):
|
||||
if isinstance(colors[0], Number):
|
||||
colors = [colors]
|
||||
else:
|
||||
colors = list(colors)
|
||||
|
||||
# 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)
|
||||
for value in each_color:
|
||||
if value > 255.0:
|
||||
raise exceptions.PlotlyError(
|
||||
"Whoops! The elements in your rgb colors "
|
||||
"tuples cannot exceed 255.0."
|
||||
)
|
||||
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."
|
||||
)
|
||||
colors[j] = each_color
|
||||
|
||||
if colortype == "rgb" and not isinstance(colors, str):
|
||||
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 dictionary 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,
|
||||
return_default_colors=False,
|
||||
num_of_defualt_colors=2,
|
||||
):
|
||||
"""
|
||||
Converts color(s) to the specified color type
|
||||
|
||||
Takes a single color or an iterable of colors, as well as a list of scale
|
||||
values, and outputs a 2-pair of the list of color(s) converted all to an
|
||||
rgb or tuple color type, aswell as the scale as the second element. If
|
||||
colors is a Plotly Scale name, then 'scale' will be forced to the scale
|
||||
from the respective colorscale and the colors in that colorscale will also
|
||||
be coverted to the selected colortype. If colors is None, then there is an
|
||||
option to return portion of the DEFAULT_PLOTLY_COLORS
|
||||
|
||||
:param (str|tuple|list) colors: either a plotly scale name, an rgb or hex
|
||||
color, a color tuple or a list/tuple of colors
|
||||
:param (list) scale: see docs for validate_scale_values()
|
||||
|
||||
:rtype (tuple) (colors_list, scale) if scale is None in the function call,
|
||||
then scale will remain None in the returned tuple
|
||||
"""
|
||||
colors_list = []
|
||||
|
||||
if colors is None and return_default_colors is True:
|
||||
colors_list = DEFAULT_PLOTLY_COLORS[0:num_of_defualt_colors]
|
||||
|
||||
if isinstance(colors, str):
|
||||
if colors in PLOTLY_SCALES:
|
||||
colors_list = colorscale_to_colors(PLOTLY_SCALES[colors])
|
||||
if scale is None:
|
||||
scale = colorscale_to_scale(PLOTLY_SCALES[colors])
|
||||
|
||||
elif "rgb" in colors or "#" in colors:
|
||||
colors_list = [colors]
|
||||
|
||||
elif isinstance(colors, tuple):
|
||||
if isinstance(colors[0], Number):
|
||||
colors_list = [colors]
|
||||
else:
|
||||
colors_list = list(colors)
|
||||
|
||||
elif isinstance(colors, list):
|
||||
colors_list = colors
|
||||
|
||||
# validate scale
|
||||
if scale is not None:
|
||||
validate_scale_values(scale)
|
||||
|
||||
if len(colors_list) != len(scale):
|
||||
raise exceptions.PlotlyError(
|
||||
"Make sure that the length of your scale matches the length "
|
||||
"of your list of colors which is {}.".format(len(colors_list))
|
||||
)
|
||||
|
||||
# convert all colors to rgb
|
||||
for j, each_color in enumerate(colors_list):
|
||||
if "#" in each_color:
|
||||
each_color = color_parser(each_color, hex_to_rgb)
|
||||
each_color = color_parser(each_color, label_rgb)
|
||||
colors_list[j] = each_color
|
||||
|
||||
elif isinstance(each_color, tuple):
|
||||
each_color = color_parser(each_color, convert_to_RGB_255)
|
||||
each_color = color_parser(each_color, label_rgb)
|
||||
colors_list[j] = each_color
|
||||
|
||||
if colortype == "rgb":
|
||||
return (colors_list, scale)
|
||||
elif colortype == "tuple":
|
||||
for j, each_color in enumerate(colors_list):
|
||||
each_color = color_parser(each_color, unlabel_rgb)
|
||||
each_color = color_parser(each_color, unconvert_from_RGB_255)
|
||||
colors_list[j] = each_color
|
||||
return (colors_list, scale)
|
||||
else:
|
||||
raise exceptions.PlotlyError(
|
||||
"You must select either rgb or tuple for your colortype variable."
|
||||
)
|
||||
|
||||
|
||||
def convert_dict_colors_to_same_type(colors_dict, colortype="rgb"):
|
||||
"""
|
||||
Converts a colors in a dictionary of colors to the specified color type
|
||||
|
||||
:param (dict) colors_dict: a dictionary whose values are single colors
|
||||
"""
|
||||
for key in colors_dict:
|
||||
if "#" in colors_dict[key]:
|
||||
colors_dict[key] = color_parser(colors_dict[key], hex_to_rgb)
|
||||
colors_dict[key] = color_parser(colors_dict[key], label_rgb)
|
||||
|
||||
elif isinstance(colors_dict[key], tuple):
|
||||
colors_dict[key] = color_parser(colors_dict[key], convert_to_RGB_255)
|
||||
colors_dict[key] = color_parser(colors_dict[key], label_rgb)
|
||||
|
||||
if colortype == "rgb":
|
||||
return colors_dict
|
||||
elif colortype == "tuple":
|
||||
for key in colors_dict:
|
||||
colors_dict[key] = color_parser(colors_dict[key], unlabel_rgb)
|
||||
colors_dict[key] = color_parser(colors_dict[key], unconvert_from_RGB_255)
|
||||
return colors_dict
|
||||
else:
|
||||
raise exceptions.PlotlyError(
|
||||
"You must select either rgb or tuple for your colortype variable."
|
||||
)
|
||||
|
||||
|
||||
def validate_scale_values(scale):
|
||||
"""
|
||||
Validates scale values from a colorscale
|
||||
|
||||
:param (list) scale: a strictly increasing list of floats that begins
|
||||
with 0 and ends with 1. Its usage derives from a colorscale which is
|
||||
a list of two-lists (a list with two elements) of the form
|
||||
[value, color] which are used to determine how interpolation weighting
|
||||
works between the colors in the colorscale. Therefore scale is just
|
||||
the extraction of these values from the two-lists in order
|
||||
"""
|
||||
if len(scale) < 2:
|
||||
raise exceptions.PlotlyError(
|
||||
"You must input a list of scale values that has at least two values."
|
||||
)
|
||||
|
||||
if (scale[0] != 0) or (scale[-1] != 1):
|
||||
raise exceptions.PlotlyError(
|
||||
"The first and last number in your scale must be 0.0 and 1.0 respectively."
|
||||
)
|
||||
|
||||
if not all(x < y for x, y in zip(scale, scale[1:])):
|
||||
raise exceptions.PlotlyError(
|
||||
"'scale' must be a list that contains a strictly increasing "
|
||||
"sequence of numbers."
|
||||
)
|
||||
|
||||
|
||||
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
|
||||
|
||||
Takes a list of colors and scales and constructs a colorscale based
|
||||
on the colors in sequential order. If 'scale' is left empty, a linear-
|
||||
interpolated colorscale will be generated. If 'scale' is a specificed
|
||||
list, it must be the same legnth as colors and must contain all floats
|
||||
For documentation regarding to the form of the output, see
|
||||
https://plot.ly/python/reference/#mesh3d-colorscale
|
||||
|
||||
:param (list) colors: a list of single colors
|
||||
"""
|
||||
colorscale = []
|
||||
|
||||
# validate minimum colors length of 2
|
||||
if len(colors) < 2:
|
||||
raise exceptions.PlotlyError(
|
||||
"You must input a list of colors that has at least two colors."
|
||||
)
|
||||
|
||||
if scale is None:
|
||||
scale_incr = 1.0 / (len(colors) - 1)
|
||||
return [[i * scale_incr, color] for i, color in enumerate(colors)]
|
||||
|
||||
else:
|
||||
if len(colors) != len(scale):
|
||||
raise exceptions.PlotlyError(
|
||||
"The length of colors and scale must be the same."
|
||||
)
|
||||
|
||||
validate_scale_values(scale)
|
||||
|
||||
colorscale = [list(tup) for tup in zip(scale, colors)]
|
||||
return colorscale
|
||||
|
||||
|
||||
def find_intermediate_color(lowcolor, highcolor, intermed, colortype="tuple"):
|
||||
"""
|
||||
Returns the color at a given distance between two colors
|
||||
|
||||
This function takes two color tuples, where each element is between 0
|
||||
and 1, along with a value 0 < intermed < 1 and returns a color that is
|
||||
intermed-percent from lowcolor to highcolor. If colortype is set to 'rgb',
|
||||
the function will automatically convert the rgb type to a tuple, find the
|
||||
intermediate color and return it as an rgb color.
|
||||
"""
|
||||
if colortype == "rgb":
|
||||
# convert to tuple color, eg. (1, 0.45, 0.7)
|
||||
lowcolor = unlabel_rgb(lowcolor)
|
||||
highcolor = unlabel_rgb(highcolor)
|
||||
|
||||
diff_0 = float(highcolor[0] - lowcolor[0])
|
||||
diff_1 = float(highcolor[1] - lowcolor[1])
|
||||
diff_2 = float(highcolor[2] - lowcolor[2])
|
||||
|
||||
inter_med_tuple = (
|
||||
lowcolor[0] + intermed * diff_0,
|
||||
lowcolor[1] + intermed * diff_1,
|
||||
lowcolor[2] + intermed * diff_2,
|
||||
)
|
||||
|
||||
if colortype == "rgb":
|
||||
# back to an rgb string, e.g. rgb(30, 20, 10)
|
||||
inter_med_rgb = label_rgb(inter_med_tuple)
|
||||
return inter_med_rgb
|
||||
|
||||
return inter_med_tuple
|
||||
|
||||
|
||||
def unconvert_from_RGB_255(colors):
|
||||
"""
|
||||
Return a tuple where each element gets divided by 255
|
||||
|
||||
Takes a (list of) color tuple(s) where each element is between 0 and
|
||||
255. Returns the same tuples where each tuple element is normalized to
|
||||
a value between 0 and 1
|
||||
"""
|
||||
return (colors[0] / (255.0), colors[1] / (255.0), colors[2] / (255.0))
|
||||
|
||||
|
||||
def convert_to_RGB_255(colors):
|
||||
"""
|
||||
Multiplies each element of a triplet by 255
|
||||
|
||||
Each coordinate of the color tuple is rounded to the nearest float and
|
||||
then is turned into an integer. If a number is of the form x.5, then
|
||||
if x is odd, the number rounds up to (x+1). Otherwise, it rounds down
|
||||
to just x. This is the way rounding works in Python 3 and in current
|
||||
statistical analysis to avoid rounding bias
|
||||
|
||||
:param (list) rgb_components: grabs the three R, G and B values to be
|
||||
returned as computed in the function
|
||||
"""
|
||||
rgb_components = []
|
||||
|
||||
for component in colors:
|
||||
rounded_num = decimal.Decimal(str(component * 255.0)).quantize(
|
||||
decimal.Decimal("1"), rounding=decimal.ROUND_HALF_EVEN
|
||||
)
|
||||
# convert rounded number to an integer from 'Decimal' form
|
||||
rounded_num = int(rounded_num)
|
||||
rgb_components.append(rounded_num)
|
||||
|
||||
return (rgb_components[0], rgb_components[1], rgb_components[2])
|
||||
|
||||
|
||||
def n_colors(lowcolor, highcolor, n_colors, colortype="tuple"):
|
||||
"""
|
||||
Splits a low and high color into a list of n_colors colors in it
|
||||
|
||||
Accepts two color tuples and returns a list of n_colors colors
|
||||
which form the intermediate colors between lowcolor and highcolor
|
||||
from linearly interpolating through RGB space. If colortype is 'rgb'
|
||||
the function will return a list of colors in the same form.
|
||||
"""
|
||||
if colortype == "rgb":
|
||||
# convert to tuple
|
||||
lowcolor = unlabel_rgb(lowcolor)
|
||||
highcolor = unlabel_rgb(highcolor)
|
||||
|
||||
diff_0 = float(highcolor[0] - lowcolor[0])
|
||||
incr_0 = diff_0 / (n_colors - 1)
|
||||
diff_1 = float(highcolor[1] - lowcolor[1])
|
||||
incr_1 = diff_1 / (n_colors - 1)
|
||||
diff_2 = float(highcolor[2] - lowcolor[2])
|
||||
incr_2 = diff_2 / (n_colors - 1)
|
||||
list_of_colors = []
|
||||
|
||||
def _constrain_color(c):
|
||||
if c > 255.0:
|
||||
return 255.0
|
||||
elif c < 0.0:
|
||||
return 0.0
|
||||
else:
|
||||
return c
|
||||
|
||||
for index in range(n_colors):
|
||||
new_tuple = (
|
||||
_constrain_color(lowcolor[0] + (index * incr_0)),
|
||||
_constrain_color(lowcolor[1] + (index * incr_1)),
|
||||
_constrain_color(lowcolor[2] + (index * incr_2)),
|
||||
)
|
||||
list_of_colors.append(new_tuple)
|
||||
|
||||
if colortype == "rgb":
|
||||
# back to an rgb string
|
||||
list_of_colors = color_parser(list_of_colors, label_rgb)
|
||||
|
||||
return list_of_colors
|
||||
|
||||
|
||||
def label_rgb(colors):
|
||||
"""
|
||||
Takes tuple (a, b, c) and returns an rgb color 'rgb(a, b, c)'
|
||||
"""
|
||||
return "rgb(%s, %s, %s)" % (colors[0], colors[1], colors[2])
|
||||
|
||||
|
||||
def unlabel_rgb(colors):
|
||||
"""
|
||||
Takes rgb color(s) 'rgb(a, b, c)' and returns tuple(s) (a, b, c)
|
||||
|
||||
This function takes either an 'rgb(a, b, c)' color or a list of
|
||||
such colors and returns the color tuples in tuple(s) (a, b, c)
|
||||
"""
|
||||
str_vals = ""
|
||||
for index in range(len(colors)):
|
||||
try:
|
||||
float(colors[index])
|
||||
str_vals = str_vals + colors[index]
|
||||
except ValueError:
|
||||
if colors[index] == "," or colors[index] == ".":
|
||||
str_vals = str_vals + colors[index]
|
||||
|
||||
str_vals = str_vals + ","
|
||||
numbers = []
|
||||
str_num = ""
|
||||
for char in str_vals:
|
||||
if char != ",":
|
||||
str_num = str_num + char
|
||||
else:
|
||||
numbers.append(float(str_num))
|
||||
str_num = ""
|
||||
return (numbers[0], numbers[1], numbers[2])
|
||||
|
||||
|
||||
def hex_to_rgb(value):
|
||||
"""
|
||||
Calculates rgb values from a hex color code.
|
||||
|
||||
:param (string) value: Hex color string
|
||||
|
||||
:rtype (tuple) (r_value, g_value, b_value): tuple of rgb values
|
||||
"""
|
||||
value = value.lstrip("#")
|
||||
hex_total_length = len(value)
|
||||
rgb_section_length = hex_total_length // 3
|
||||
return tuple(
|
||||
int(value[i : i + rgb_section_length], 16)
|
||||
for i in range(0, hex_total_length, rgb_section_length)
|
||||
)
|
||||
|
||||
|
||||
def colorscale_to_colors(colorscale):
|
||||
"""
|
||||
Extracts the colors from colorscale as a list
|
||||
"""
|
||||
color_list = []
|
||||
for item in colorscale:
|
||||
color_list.append(item[1])
|
||||
return color_list
|
||||
|
||||
|
||||
def colorscale_to_scale(colorscale):
|
||||
"""
|
||||
Extracts the interpolation scale values from colorscale as a list
|
||||
"""
|
||||
scale_list = []
|
||||
for item in colorscale:
|
||||
scale_list.append(item[0])
|
||||
return scale_list
|
||||
|
||||
|
||||
def convert_colorscale_to_rgb(colorscale):
|
||||
"""
|
||||
Converts the colors in a colorscale to rgb colors
|
||||
|
||||
A colorscale is an array of arrays, each with a numeric value as the
|
||||
first item and a color as the second. This function specifically is
|
||||
converting a colorscale with tuple colors (each coordinate between 0
|
||||
and 1) into a colorscale with the colors transformed into rgb colors
|
||||
"""
|
||||
for color in colorscale:
|
||||
color[1] = convert_to_RGB_255(color[1])
|
||||
|
||||
for color in colorscale:
|
||||
color[1] = label_rgb(color[1])
|
||||
return colorscale
|
||||
|
||||
|
||||
def named_colorscales():
|
||||
"""
|
||||
Returns lowercased names of built-in continuous colorscales.
|
||||
"""
|
||||
from _plotly_utils.basevalidators import ColorscaleValidator
|
||||
|
||||
return [c for c in ColorscaleValidator("", "").named_colorscales]
|
||||
|
||||
|
||||
def get_colorscale(name):
|
||||
"""
|
||||
Returns the colorscale for a given name. See `named_colorscales` for the
|
||||
built-in colorscales.
|
||||
"""
|
||||
from _plotly_utils.basevalidators import ColorscaleValidator
|
||||
|
||||
if not isinstance(name, str):
|
||||
raise exceptions.PlotlyError("Name argument have to be a string.")
|
||||
|
||||
name = name.lower()
|
||||
if name[-2:] == "_r":
|
||||
should_reverse = True
|
||||
name = name[:-2]
|
||||
else:
|
||||
should_reverse = False
|
||||
|
||||
if name in ColorscaleValidator("", "").named_colorscales:
|
||||
colorscale = ColorscaleValidator("", "").named_colorscales[name]
|
||||
else:
|
||||
raise exceptions.PlotlyError(f"Colorscale {name} is not a built-in scale.")
|
||||
|
||||
if should_reverse:
|
||||
colorscale = colorscale[::-1]
|
||||
return make_colorscale(colorscale)
|
||||
|
||||
|
||||
def sample_colorscale(colorscale, samplepoints, low=0.0, high=1.0, colortype="rgb"):
|
||||
"""
|
||||
Samples a colorscale at specific points.
|
||||
|
||||
Interpolates between colors in a colorscale to find the specific colors
|
||||
corresponding to the specified sample values. The colorscale can be specified
|
||||
as a list of `[scale, color]` pairs, as a list of colors, or as a named
|
||||
plotly colorscale. The samplepoints can be specefied as an iterable of specific
|
||||
points in the range [0.0, 1.0], or as an integer number of points which will
|
||||
be spaced equally between the low value (default 0.0) and the high value
|
||||
(default 1.0). The output is a list of colors, formatted according to the
|
||||
specified colortype.
|
||||
"""
|
||||
from bisect import bisect_left
|
||||
|
||||
try:
|
||||
validate_colorscale(colorscale)
|
||||
except exceptions.PlotlyError:
|
||||
if isinstance(colorscale, str):
|
||||
colorscale = get_colorscale(colorscale)
|
||||
else:
|
||||
colorscale = make_colorscale(colorscale)
|
||||
|
||||
scale = colorscale_to_scale(colorscale)
|
||||
validate_scale_values(scale)
|
||||
colors = colorscale_to_colors(colorscale)
|
||||
colors = validate_colors(colors, colortype="tuple")
|
||||
|
||||
if isinstance(samplepoints, int):
|
||||
samplepoints = [
|
||||
low + idx / (samplepoints - 1) * (high - low) for idx in range(samplepoints)
|
||||
]
|
||||
elif isinstance(samplepoints, float):
|
||||
samplepoints = [samplepoints]
|
||||
|
||||
sampled_colors = []
|
||||
for point in samplepoints:
|
||||
high = bisect_left(scale, point)
|
||||
low = high - 1
|
||||
interpolant = (point - scale[low]) / (scale[high] - scale[low])
|
||||
sampled_color = find_intermediate_color(colors[low], colors[high], interpolant)
|
||||
sampled_colors.append(sampled_color)
|
||||
return validate_colors(sampled_colors, colortype=colortype)
|
161
lib/python3.11/site-packages/_plotly_utils/colors/_swatches.py
Normal file
161
lib/python3.11/site-packages/_plotly_utils/colors/_swatches.py
Normal file
@ -0,0 +1,161 @@
|
||||
def _swatches(module_names, module_contents, template=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
template : str or dict or plotly.graph_objects.layout.Template instance
|
||||
The figure template name or definition.
|
||||
|
||||
Returns
|
||||
-------
|
||||
fig : graph_objects.Figure containing the displayed image
|
||||
A `Figure` object. This figure demonstrates the color scales and
|
||||
sequences in this module, as stacked bar charts.
|
||||
"""
|
||||
import plotly.graph_objs as go
|
||||
from plotly.express._core import apply_default_cascade
|
||||
|
||||
args = dict(template=template)
|
||||
apply_default_cascade(args)
|
||||
|
||||
sequences = [
|
||||
(k, v)
|
||||
for k, v in module_contents.items()
|
||||
if not (k.startswith("_") or k.startswith("swatches") or k.endswith("_r"))
|
||||
]
|
||||
|
||||
return go.Figure(
|
||||
data=[
|
||||
go.Bar(
|
||||
orientation="h",
|
||||
y=[name] * len(colors),
|
||||
x=[1] * len(colors),
|
||||
customdata=list(range(len(colors))),
|
||||
marker=dict(color=colors),
|
||||
hovertemplate="%{y}[%{customdata}] = %{marker.color}<extra></extra>",
|
||||
)
|
||||
for name, colors in reversed(sequences)
|
||||
],
|
||||
layout=dict(
|
||||
title="plotly.colors." + module_names.split(".")[-1],
|
||||
barmode="stack",
|
||||
barnorm="fraction",
|
||||
bargap=0.5,
|
||||
showlegend=False,
|
||||
xaxis=dict(range=[-0.02, 1.02], showticklabels=False, showgrid=False),
|
||||
height=max(600, 40 * len(sequences)),
|
||||
template=args["template"],
|
||||
margin=dict(b=10),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _swatches_continuous(module_names, module_contents, template=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
template : str or dict or plotly.graph_objects.layout.Template instance
|
||||
The figure template name or definition.
|
||||
|
||||
Returns
|
||||
-------
|
||||
fig : graph_objects.Figure containing the displayed image
|
||||
A `Figure` object. This figure demonstrates the color scales and
|
||||
sequences in this module, as stacked bar charts.
|
||||
"""
|
||||
import plotly.graph_objs as go
|
||||
from plotly.express._core import apply_default_cascade
|
||||
|
||||
args = dict(template=template)
|
||||
apply_default_cascade(args)
|
||||
|
||||
sequences = [
|
||||
(k, v)
|
||||
for k, v in module_contents.items()
|
||||
if not (k.startswith("_") or k.startswith("swatches") or k.endswith("_r"))
|
||||
]
|
||||
|
||||
n = 100
|
||||
|
||||
return go.Figure(
|
||||
data=[
|
||||
go.Bar(
|
||||
orientation="h",
|
||||
y=[name] * n,
|
||||
x=[1] * n,
|
||||
customdata=[(x + 1) / n for x in range(n)],
|
||||
marker=dict(color=list(range(n)), colorscale=name, line_width=0),
|
||||
hovertemplate="%{customdata}",
|
||||
name=name,
|
||||
)
|
||||
for name, colors in reversed(sequences)
|
||||
],
|
||||
layout=dict(
|
||||
title="plotly.colors." + module_names.split(".")[-1],
|
||||
barmode="stack",
|
||||
barnorm="fraction",
|
||||
bargap=0.3,
|
||||
showlegend=False,
|
||||
xaxis=dict(range=[-0.02, 1.02], showticklabels=False, showgrid=False),
|
||||
height=max(600, 40 * len(sequences)),
|
||||
width=500,
|
||||
template=args["template"],
|
||||
margin=dict(b=10),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _swatches_cyclical(module_names, module_contents, template=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
template : str or dict or plotly.graph_objects.layout.Template instance
|
||||
The figure template name or definition.
|
||||
|
||||
Returns
|
||||
-------
|
||||
fig : graph_objects.Figure containing the displayed image
|
||||
A `Figure` object. This figure demonstrates the color scales and
|
||||
sequences in this module, as polar bar charts.
|
||||
"""
|
||||
import plotly.graph_objects as go
|
||||
from plotly.subplots import make_subplots
|
||||
from plotly.express._core import apply_default_cascade
|
||||
|
||||
args = dict(template=template)
|
||||
apply_default_cascade(args)
|
||||
|
||||
rows = 2
|
||||
cols = 4
|
||||
scales = [
|
||||
(k, v)
|
||||
for k, v in module_contents.items()
|
||||
if not (k.startswith("_") or k.startswith("swatches") or k.endswith("_r"))
|
||||
]
|
||||
names = [name for name, colors in scales]
|
||||
fig = make_subplots(
|
||||
rows=rows,
|
||||
cols=cols,
|
||||
subplot_titles=names,
|
||||
specs=[[{"type": "polar"}] * cols] * rows,
|
||||
)
|
||||
|
||||
for i, (name, scale) in enumerate(scales):
|
||||
fig.add_trace(
|
||||
go.Barpolar(
|
||||
r=[1] * int(360 / 5),
|
||||
theta=list(range(0, 360, 5)),
|
||||
marker_color=list(range(0, 360, 5)),
|
||||
marker_cmin=0,
|
||||
marker_cmax=360,
|
||||
marker_colorscale=name,
|
||||
name=name,
|
||||
),
|
||||
row=int(i / cols) + 1,
|
||||
col=i % cols + 1,
|
||||
)
|
||||
fig.update_traces(width=5.2, marker_line_width=0, base=0.5, showlegend=False)
|
||||
fig.update_polars(angularaxis_visible=False, radialaxis_visible=False)
|
||||
fig.update_layout(
|
||||
title="plotly.colors." + module_names.split(".")[-1], template=args["template"]
|
||||
)
|
||||
return fig
|
419
lib/python3.11/site-packages/_plotly_utils/colors/carto.py
Normal file
419
lib/python3.11/site-packages/_plotly_utils/colors/carto.py
Normal file
@ -0,0 +1,419 @@
|
||||
"""
|
||||
Color sequences and scales from CARTO's CartoColors
|
||||
|
||||
Learn more at https://github.com/CartoDB/CartoColor
|
||||
|
||||
CARTOColors are made available under a Creative Commons Attribution license: https://creativecommons.org/licenses/by/3.0/us/
|
||||
"""
|
||||
|
||||
from ._swatches import _swatches
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
Burg = [
|
||||
"rgb(255, 198, 196)",
|
||||
"rgb(244, 163, 168)",
|
||||
"rgb(227, 129, 145)",
|
||||
"rgb(204, 96, 125)",
|
||||
"rgb(173, 70, 108)",
|
||||
"rgb(139, 48, 88)",
|
||||
"rgb(103, 32, 68)",
|
||||
]
|
||||
|
||||
Burgyl = [
|
||||
"rgb(251, 230, 197)",
|
||||
"rgb(245, 186, 152)",
|
||||
"rgb(238, 138, 130)",
|
||||
"rgb(220, 113, 118)",
|
||||
"rgb(200, 88, 108)",
|
||||
"rgb(156, 63, 93)",
|
||||
"rgb(112, 40, 74)",
|
||||
]
|
||||
|
||||
Redor = [
|
||||
"rgb(246, 210, 169)",
|
||||
"rgb(245, 183, 142)",
|
||||
"rgb(241, 156, 124)",
|
||||
"rgb(234, 129, 113)",
|
||||
"rgb(221, 104, 108)",
|
||||
"rgb(202, 82, 104)",
|
||||
"rgb(177, 63, 100)",
|
||||
]
|
||||
|
||||
Oryel = [
|
||||
"rgb(236, 218, 154)",
|
||||
"rgb(239, 196, 126)",
|
||||
"rgb(243, 173, 106)",
|
||||
"rgb(247, 148, 93)",
|
||||
"rgb(249, 123, 87)",
|
||||
"rgb(246, 99, 86)",
|
||||
"rgb(238, 77, 90)",
|
||||
]
|
||||
|
||||
Peach = [
|
||||
"rgb(253, 224, 197)",
|
||||
"rgb(250, 203, 166)",
|
||||
"rgb(248, 181, 139)",
|
||||
"rgb(245, 158, 114)",
|
||||
"rgb(242, 133, 93)",
|
||||
"rgb(239, 106, 76)",
|
||||
"rgb(235, 74, 64)",
|
||||
]
|
||||
|
||||
Pinkyl = [
|
||||
"rgb(254, 246, 181)",
|
||||
"rgb(255, 221, 154)",
|
||||
"rgb(255, 194, 133)",
|
||||
"rgb(255, 166, 121)",
|
||||
"rgb(250, 138, 118)",
|
||||
"rgb(241, 109, 122)",
|
||||
"rgb(225, 83, 131)",
|
||||
]
|
||||
|
||||
Mint = [
|
||||
"rgb(228, 241, 225)",
|
||||
"rgb(180, 217, 204)",
|
||||
"rgb(137, 192, 182)",
|
||||
"rgb(99, 166, 160)",
|
||||
"rgb(68, 140, 138)",
|
||||
"rgb(40, 114, 116)",
|
||||
"rgb(13, 88, 95)",
|
||||
]
|
||||
|
||||
Blugrn = [
|
||||
"rgb(196, 230, 195)",
|
||||
"rgb(150, 210, 164)",
|
||||
"rgb(109, 188, 144)",
|
||||
"rgb(77, 162, 132)",
|
||||
"rgb(54, 135, 122)",
|
||||
"rgb(38, 107, 110)",
|
||||
"rgb(29, 79, 96)",
|
||||
]
|
||||
|
||||
Darkmint = [
|
||||
"rgb(210, 251, 212)",
|
||||
"rgb(165, 219, 194)",
|
||||
"rgb(123, 188, 176)",
|
||||
"rgb(85, 156, 158)",
|
||||
"rgb(58, 124, 137)",
|
||||
"rgb(35, 93, 114)",
|
||||
"rgb(18, 63, 90)",
|
||||
]
|
||||
|
||||
Emrld = [
|
||||
"rgb(211, 242, 163)",
|
||||
"rgb(151, 225, 150)",
|
||||
"rgb(108, 192, 139)",
|
||||
"rgb(76, 155, 130)",
|
||||
"rgb(33, 122, 121)",
|
||||
"rgb(16, 89, 101)",
|
||||
"rgb(7, 64, 80)",
|
||||
]
|
||||
|
||||
Aggrnyl = [
|
||||
"rgb(36, 86, 104)",
|
||||
"rgb(15, 114, 121)",
|
||||
"rgb(13, 143, 129)",
|
||||
"rgb(57, 171, 126)",
|
||||
"rgb(110, 197, 116)",
|
||||
"rgb(169, 220, 103)",
|
||||
"rgb(237, 239, 93)",
|
||||
]
|
||||
|
||||
Bluyl = [
|
||||
"rgb(247, 254, 174)",
|
||||
"rgb(183, 230, 165)",
|
||||
"rgb(124, 203, 162)",
|
||||
"rgb(70, 174, 160)",
|
||||
"rgb(8, 144, 153)",
|
||||
"rgb(0, 113, 139)",
|
||||
"rgb(4, 82, 117)",
|
||||
]
|
||||
|
||||
Teal = [
|
||||
"rgb(209, 238, 234)",
|
||||
"rgb(168, 219, 217)",
|
||||
"rgb(133, 196, 201)",
|
||||
"rgb(104, 171, 184)",
|
||||
"rgb(79, 144, 166)",
|
||||
"rgb(59, 115, 143)",
|
||||
"rgb(42, 86, 116)",
|
||||
]
|
||||
|
||||
Tealgrn = [
|
||||
"rgb(176, 242, 188)",
|
||||
"rgb(137, 232, 172)",
|
||||
"rgb(103, 219, 165)",
|
||||
"rgb(76, 200, 163)",
|
||||
"rgb(56, 178, 163)",
|
||||
"rgb(44, 152, 160)",
|
||||
"rgb(37, 125, 152)",
|
||||
]
|
||||
|
||||
Purp = [
|
||||
"rgb(243, 224, 247)",
|
||||
"rgb(228, 199, 241)",
|
||||
"rgb(209, 175, 232)",
|
||||
"rgb(185, 152, 221)",
|
||||
"rgb(159, 130, 206)",
|
||||
"rgb(130, 109, 186)",
|
||||
"rgb(99, 88, 159)",
|
||||
]
|
||||
|
||||
Purpor = [
|
||||
"rgb(249, 221, 218)",
|
||||
"rgb(242, 185, 196)",
|
||||
"rgb(229, 151, 185)",
|
||||
"rgb(206, 120, 179)",
|
||||
"rgb(173, 95, 173)",
|
||||
"rgb(131, 75, 160)",
|
||||
"rgb(87, 59, 136)",
|
||||
]
|
||||
|
||||
Sunset = [
|
||||
"rgb(243, 231, 155)",
|
||||
"rgb(250, 196, 132)",
|
||||
"rgb(248, 160, 126)",
|
||||
"rgb(235, 127, 134)",
|
||||
"rgb(206, 102, 147)",
|
||||
"rgb(160, 89, 160)",
|
||||
"rgb(92, 83, 165)",
|
||||
]
|
||||
|
||||
Magenta = [
|
||||
"rgb(243, 203, 211)",
|
||||
"rgb(234, 169, 189)",
|
||||
"rgb(221, 136, 172)",
|
||||
"rgb(202, 105, 157)",
|
||||
"rgb(177, 77, 142)",
|
||||
"rgb(145, 53, 125)",
|
||||
"rgb(108, 33, 103)",
|
||||
]
|
||||
|
||||
Sunsetdark = [
|
||||
"rgb(252, 222, 156)",
|
||||
"rgb(250, 164, 118)",
|
||||
"rgb(240, 116, 110)",
|
||||
"rgb(227, 79, 111)",
|
||||
"rgb(220, 57, 119)",
|
||||
"rgb(185, 37, 122)",
|
||||
"rgb(124, 29, 111)",
|
||||
]
|
||||
|
||||
Agsunset = [
|
||||
"rgb(75, 41, 145)",
|
||||
"rgb(135, 44, 162)",
|
||||
"rgb(192, 54, 157)",
|
||||
"rgb(234, 79, 136)",
|
||||
"rgb(250, 120, 118)",
|
||||
"rgb(246, 169, 122)",
|
||||
"rgb(237, 217, 163)",
|
||||
]
|
||||
|
||||
Brwnyl = [
|
||||
"rgb(237, 229, 207)",
|
||||
"rgb(224, 194, 162)",
|
||||
"rgb(211, 156, 131)",
|
||||
"rgb(193, 118, 111)",
|
||||
"rgb(166, 84, 97)",
|
||||
"rgb(129, 55, 83)",
|
||||
"rgb(84, 31, 63)",
|
||||
]
|
||||
|
||||
# Diverging schemes
|
||||
|
||||
Armyrose = [
|
||||
"rgb(121, 130, 52)",
|
||||
"rgb(163, 173, 98)",
|
||||
"rgb(208, 211, 162)",
|
||||
"rgb(253, 251, 228)",
|
||||
"rgb(240, 198, 195)",
|
||||
"rgb(223, 145, 163)",
|
||||
"rgb(212, 103, 128)",
|
||||
]
|
||||
|
||||
Fall = [
|
||||
"rgb(61, 89, 65)",
|
||||
"rgb(119, 136, 104)",
|
||||
"rgb(181, 185, 145)",
|
||||
"rgb(246, 237, 189)",
|
||||
"rgb(237, 187, 138)",
|
||||
"rgb(222, 138, 90)",
|
||||
"rgb(202, 86, 44)",
|
||||
]
|
||||
|
||||
Geyser = [
|
||||
"rgb(0, 128, 128)",
|
||||
"rgb(112, 164, 148)",
|
||||
"rgb(180, 200, 168)",
|
||||
"rgb(246, 237, 189)",
|
||||
"rgb(237, 187, 138)",
|
||||
"rgb(222, 138, 90)",
|
||||
"rgb(202, 86, 44)",
|
||||
]
|
||||
|
||||
Temps = [
|
||||
"rgb(0, 147, 146)",
|
||||
"rgb(57, 177, 133)",
|
||||
"rgb(156, 203, 134)",
|
||||
"rgb(233, 226, 156)",
|
||||
"rgb(238, 180, 121)",
|
||||
"rgb(232, 132, 113)",
|
||||
"rgb(207, 89, 126)",
|
||||
]
|
||||
|
||||
Tealrose = [
|
||||
"rgb(0, 147, 146)",
|
||||
"rgb(114, 170, 161)",
|
||||
"rgb(177, 199, 179)",
|
||||
"rgb(241, 234, 200)",
|
||||
"rgb(229, 185, 173)",
|
||||
"rgb(217, 137, 148)",
|
||||
"rgb(208, 88, 126)",
|
||||
]
|
||||
|
||||
Tropic = [
|
||||
"rgb(0, 155, 158)",
|
||||
"rgb(66, 183, 185)",
|
||||
"rgb(167, 211, 212)",
|
||||
"rgb(241, 241, 241)",
|
||||
"rgb(228, 193, 217)",
|
||||
"rgb(214, 145, 193)",
|
||||
"rgb(199, 93, 171)",
|
||||
]
|
||||
|
||||
Earth = [
|
||||
"rgb(161, 105, 40)",
|
||||
"rgb(189, 146, 90)",
|
||||
"rgb(214, 189, 141)",
|
||||
"rgb(237, 234, 194)",
|
||||
"rgb(181, 200, 184)",
|
||||
"rgb(121, 167, 172)",
|
||||
"rgb(40, 135, 161)",
|
||||
]
|
||||
|
||||
# Qualitative palettes
|
||||
|
||||
Antique = [
|
||||
"rgb(133, 92, 117)",
|
||||
"rgb(217, 175, 107)",
|
||||
"rgb(175, 100, 88)",
|
||||
"rgb(115, 111, 76)",
|
||||
"rgb(82, 106, 131)",
|
||||
"rgb(98, 83, 119)",
|
||||
"rgb(104, 133, 92)",
|
||||
"rgb(156, 156, 94)",
|
||||
"rgb(160, 97, 119)",
|
||||
"rgb(140, 120, 93)",
|
||||
"rgb(124, 124, 124)",
|
||||
]
|
||||
|
||||
Bold = [
|
||||
"rgb(127, 60, 141)",
|
||||
"rgb(17, 165, 121)",
|
||||
"rgb(57, 105, 172)",
|
||||
"rgb(242, 183, 1)",
|
||||
"rgb(231, 63, 116)",
|
||||
"rgb(128, 186, 90)",
|
||||
"rgb(230, 131, 16)",
|
||||
"rgb(0, 134, 149)",
|
||||
"rgb(207, 28, 144)",
|
||||
"rgb(249, 123, 114)",
|
||||
"rgb(165, 170, 153)",
|
||||
]
|
||||
|
||||
Pastel = [
|
||||
"rgb(102, 197, 204)",
|
||||
"rgb(246, 207, 113)",
|
||||
"rgb(248, 156, 116)",
|
||||
"rgb(220, 176, 242)",
|
||||
"rgb(135, 197, 95)",
|
||||
"rgb(158, 185, 243)",
|
||||
"rgb(254, 136, 177)",
|
||||
"rgb(201, 219, 116)",
|
||||
"rgb(139, 224, 164)",
|
||||
"rgb(180, 151, 231)",
|
||||
"rgb(179, 179, 179)",
|
||||
]
|
||||
|
||||
Prism = [
|
||||
"rgb(95, 70, 144)",
|
||||
"rgb(29, 105, 150)",
|
||||
"rgb(56, 166, 165)",
|
||||
"rgb(15, 133, 84)",
|
||||
"rgb(115, 175, 72)",
|
||||
"rgb(237, 173, 8)",
|
||||
"rgb(225, 124, 5)",
|
||||
"rgb(204, 80, 62)",
|
||||
"rgb(148, 52, 110)",
|
||||
"rgb(111, 64, 112)",
|
||||
"rgb(102, 102, 102)",
|
||||
]
|
||||
|
||||
Safe = [
|
||||
"rgb(136, 204, 238)",
|
||||
"rgb(204, 102, 119)",
|
||||
"rgb(221, 204, 119)",
|
||||
"rgb(17, 119, 51)",
|
||||
"rgb(51, 34, 136)",
|
||||
"rgb(170, 68, 153)",
|
||||
"rgb(68, 170, 153)",
|
||||
"rgb(153, 153, 51)",
|
||||
"rgb(136, 34, 85)",
|
||||
"rgb(102, 17, 0)",
|
||||
"rgb(136, 136, 136)",
|
||||
]
|
||||
|
||||
Vivid = [
|
||||
"rgb(229, 134, 6)",
|
||||
"rgb(93, 105, 177)",
|
||||
"rgb(82, 188, 163)",
|
||||
"rgb(153, 201, 69)",
|
||||
"rgb(204, 97, 176)",
|
||||
"rgb(36, 121, 108)",
|
||||
"rgb(218, 165, 27)",
|
||||
"rgb(47, 138, 196)",
|
||||
"rgb(118, 78, 159)",
|
||||
"rgb(237, 100, 90)",
|
||||
"rgb(165, 170, 153)",
|
||||
]
|
||||
|
||||
Aggrnyl_r = Aggrnyl[::-1]
|
||||
Agsunset_r = Agsunset[::-1]
|
||||
Antique_r = Antique[::-1]
|
||||
Armyrose_r = Armyrose[::-1]
|
||||
Blugrn_r = Blugrn[::-1]
|
||||
Bluyl_r = Bluyl[::-1]
|
||||
Bold_r = Bold[::-1]
|
||||
Brwnyl_r = Brwnyl[::-1]
|
||||
Burg_r = Burg[::-1]
|
||||
Burgyl_r = Burgyl[::-1]
|
||||
Darkmint_r = Darkmint[::-1]
|
||||
Earth_r = Earth[::-1]
|
||||
Emrld_r = Emrld[::-1]
|
||||
Fall_r = Fall[::-1]
|
||||
Geyser_r = Geyser[::-1]
|
||||
Magenta_r = Magenta[::-1]
|
||||
Mint_r = Mint[::-1]
|
||||
Oryel_r = Oryel[::-1]
|
||||
Pastel_r = Pastel[::-1]
|
||||
Peach_r = Peach[::-1]
|
||||
Pinkyl_r = Pinkyl[::-1]
|
||||
Prism_r = Prism[::-1]
|
||||
Purp_r = Purp[::-1]
|
||||
Purpor_r = Purpor[::-1]
|
||||
Redor_r = Redor[::-1]
|
||||
Safe_r = Safe[::-1]
|
||||
Sunset_r = Sunset[::-1]
|
||||
Sunsetdark_r = Sunsetdark[::-1]
|
||||
Teal_r = Teal[::-1]
|
||||
Tealgrn_r = Tealgrn[::-1]
|
||||
Tealrose_r = Tealrose[::-1]
|
||||
Temps_r = Temps[::-1]
|
||||
Tropic_r = Tropic[::-1]
|
||||
Vivid_r = Vivid[::-1]
|
296
lib/python3.11/site-packages/_plotly_utils/colors/cmocean.py
Normal file
296
lib/python3.11/site-packages/_plotly_utils/colors/cmocean.py
Normal file
@ -0,0 +1,296 @@
|
||||
"""
|
||||
Color scales from the cmocean project
|
||||
|
||||
Learn more at https://matplotlib.org/cmocean/
|
||||
|
||||
cmocean is made available under an MIT license: https://github.com/matplotlib/cmocean/blob/master/LICENSE.txt
|
||||
"""
|
||||
|
||||
from ._swatches import _swatches, _swatches_continuous
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
|
||||
def swatches_continuous(template=None):
|
||||
return _swatches_continuous(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches_continuous.__doc__ = _swatches_continuous.__doc__
|
||||
|
||||
|
||||
turbid = [
|
||||
"rgb(232, 245, 171)",
|
||||
"rgb(220, 219, 137)",
|
||||
"rgb(209, 193, 107)",
|
||||
"rgb(199, 168, 83)",
|
||||
"rgb(186, 143, 66)",
|
||||
"rgb(170, 121, 60)",
|
||||
"rgb(151, 103, 58)",
|
||||
"rgb(129, 87, 56)",
|
||||
"rgb(104, 72, 53)",
|
||||
"rgb(80, 59, 46)",
|
||||
"rgb(57, 45, 37)",
|
||||
"rgb(34, 30, 27)",
|
||||
]
|
||||
thermal = [
|
||||
"rgb(3, 35, 51)",
|
||||
"rgb(13, 48, 100)",
|
||||
"rgb(53, 50, 155)",
|
||||
"rgb(93, 62, 153)",
|
||||
"rgb(126, 77, 143)",
|
||||
"rgb(158, 89, 135)",
|
||||
"rgb(193, 100, 121)",
|
||||
"rgb(225, 113, 97)",
|
||||
"rgb(246, 139, 69)",
|
||||
"rgb(251, 173, 60)",
|
||||
"rgb(246, 211, 70)",
|
||||
"rgb(231, 250, 90)",
|
||||
]
|
||||
haline = [
|
||||
"rgb(41, 24, 107)",
|
||||
"rgb(42, 35, 160)",
|
||||
"rgb(15, 71, 153)",
|
||||
"rgb(18, 95, 142)",
|
||||
"rgb(38, 116, 137)",
|
||||
"rgb(53, 136, 136)",
|
||||
"rgb(65, 157, 133)",
|
||||
"rgb(81, 178, 124)",
|
||||
"rgb(111, 198, 107)",
|
||||
"rgb(160, 214, 91)",
|
||||
"rgb(212, 225, 112)",
|
||||
"rgb(253, 238, 153)",
|
||||
]
|
||||
solar = [
|
||||
"rgb(51, 19, 23)",
|
||||
"rgb(79, 28, 33)",
|
||||
"rgb(108, 36, 36)",
|
||||
"rgb(135, 47, 32)",
|
||||
"rgb(157, 66, 25)",
|
||||
"rgb(174, 88, 20)",
|
||||
"rgb(188, 111, 19)",
|
||||
"rgb(199, 137, 22)",
|
||||
"rgb(209, 164, 32)",
|
||||
"rgb(217, 192, 44)",
|
||||
"rgb(222, 222, 59)",
|
||||
"rgb(224, 253, 74)",
|
||||
]
|
||||
ice = [
|
||||
"rgb(3, 5, 18)",
|
||||
"rgb(25, 25, 51)",
|
||||
"rgb(44, 42, 87)",
|
||||
"rgb(58, 60, 125)",
|
||||
"rgb(62, 83, 160)",
|
||||
"rgb(62, 109, 178)",
|
||||
"rgb(72, 134, 187)",
|
||||
"rgb(89, 159, 196)",
|
||||
"rgb(114, 184, 205)",
|
||||
"rgb(149, 207, 216)",
|
||||
"rgb(192, 229, 232)",
|
||||
"rgb(234, 252, 253)",
|
||||
]
|
||||
gray = [
|
||||
"rgb(0, 0, 0)",
|
||||
"rgb(16, 16, 16)",
|
||||
"rgb(38, 38, 38)",
|
||||
"rgb(59, 59, 59)",
|
||||
"rgb(81, 80, 80)",
|
||||
"rgb(102, 101, 101)",
|
||||
"rgb(124, 123, 122)",
|
||||
"rgb(146, 146, 145)",
|
||||
"rgb(171, 171, 170)",
|
||||
"rgb(197, 197, 195)",
|
||||
"rgb(224, 224, 223)",
|
||||
"rgb(254, 254, 253)",
|
||||
]
|
||||
oxy = [
|
||||
"rgb(63, 5, 5)",
|
||||
"rgb(101, 6, 13)",
|
||||
"rgb(138, 17, 9)",
|
||||
"rgb(96, 95, 95)",
|
||||
"rgb(119, 118, 118)",
|
||||
"rgb(142, 141, 141)",
|
||||
"rgb(166, 166, 165)",
|
||||
"rgb(193, 192, 191)",
|
||||
"rgb(222, 222, 220)",
|
||||
"rgb(239, 248, 90)",
|
||||
"rgb(230, 210, 41)",
|
||||
"rgb(220, 174, 25)",
|
||||
]
|
||||
deep = [
|
||||
"rgb(253, 253, 204)",
|
||||
"rgb(206, 236, 179)",
|
||||
"rgb(156, 219, 165)",
|
||||
"rgb(111, 201, 163)",
|
||||
"rgb(86, 177, 163)",
|
||||
"rgb(76, 153, 160)",
|
||||
"rgb(68, 130, 155)",
|
||||
"rgb(62, 108, 150)",
|
||||
"rgb(62, 82, 143)",
|
||||
"rgb(64, 60, 115)",
|
||||
"rgb(54, 43, 77)",
|
||||
"rgb(39, 26, 44)",
|
||||
]
|
||||
dense = [
|
||||
"rgb(230, 240, 240)",
|
||||
"rgb(191, 221, 229)",
|
||||
"rgb(156, 201, 226)",
|
||||
"rgb(129, 180, 227)",
|
||||
"rgb(115, 154, 228)",
|
||||
"rgb(117, 127, 221)",
|
||||
"rgb(120, 100, 202)",
|
||||
"rgb(119, 74, 175)",
|
||||
"rgb(113, 50, 141)",
|
||||
"rgb(100, 31, 104)",
|
||||
"rgb(80, 20, 66)",
|
||||
"rgb(54, 14, 36)",
|
||||
]
|
||||
algae = [
|
||||
"rgb(214, 249, 207)",
|
||||
"rgb(186, 228, 174)",
|
||||
"rgb(156, 209, 143)",
|
||||
"rgb(124, 191, 115)",
|
||||
"rgb(85, 174, 91)",
|
||||
"rgb(37, 157, 81)",
|
||||
"rgb(7, 138, 78)",
|
||||
"rgb(13, 117, 71)",
|
||||
"rgb(23, 95, 61)",
|
||||
"rgb(25, 75, 49)",
|
||||
"rgb(23, 55, 35)",
|
||||
"rgb(17, 36, 20)",
|
||||
]
|
||||
matter = [
|
||||
"rgb(253, 237, 176)",
|
||||
"rgb(250, 205, 145)",
|
||||
"rgb(246, 173, 119)",
|
||||
"rgb(240, 142, 98)",
|
||||
"rgb(231, 109, 84)",
|
||||
"rgb(216, 80, 83)",
|
||||
"rgb(195, 56, 90)",
|
||||
"rgb(168, 40, 96)",
|
||||
"rgb(138, 29, 99)",
|
||||
"rgb(107, 24, 93)",
|
||||
"rgb(76, 21, 80)",
|
||||
"rgb(47, 15, 61)",
|
||||
]
|
||||
speed = [
|
||||
"rgb(254, 252, 205)",
|
||||
"rgb(239, 225, 156)",
|
||||
"rgb(221, 201, 106)",
|
||||
"rgb(194, 182, 59)",
|
||||
"rgb(157, 167, 21)",
|
||||
"rgb(116, 153, 5)",
|
||||
"rgb(75, 138, 20)",
|
||||
"rgb(35, 121, 36)",
|
||||
"rgb(11, 100, 44)",
|
||||
"rgb(18, 78, 43)",
|
||||
"rgb(25, 56, 34)",
|
||||
"rgb(23, 35, 18)",
|
||||
]
|
||||
amp = [
|
||||
"rgb(241, 236, 236)",
|
||||
"rgb(230, 209, 203)",
|
||||
"rgb(221, 182, 170)",
|
||||
"rgb(213, 156, 137)",
|
||||
"rgb(205, 129, 103)",
|
||||
"rgb(196, 102, 73)",
|
||||
"rgb(186, 74, 47)",
|
||||
"rgb(172, 44, 36)",
|
||||
"rgb(149, 19, 39)",
|
||||
"rgb(120, 14, 40)",
|
||||
"rgb(89, 13, 31)",
|
||||
"rgb(60, 9, 17)",
|
||||
]
|
||||
tempo = [
|
||||
"rgb(254, 245, 244)",
|
||||
"rgb(222, 224, 210)",
|
||||
"rgb(189, 206, 181)",
|
||||
"rgb(153, 189, 156)",
|
||||
"rgb(110, 173, 138)",
|
||||
"rgb(65, 157, 129)",
|
||||
"rgb(25, 137, 125)",
|
||||
"rgb(18, 116, 117)",
|
||||
"rgb(25, 94, 106)",
|
||||
"rgb(28, 72, 93)",
|
||||
"rgb(25, 51, 80)",
|
||||
"rgb(20, 29, 67)",
|
||||
]
|
||||
phase = [
|
||||
"rgb(167, 119, 12)",
|
||||
"rgb(197, 96, 51)",
|
||||
"rgb(217, 67, 96)",
|
||||
"rgb(221, 38, 163)",
|
||||
"rgb(196, 59, 224)",
|
||||
"rgb(153, 97, 244)",
|
||||
"rgb(95, 127, 228)",
|
||||
"rgb(40, 144, 183)",
|
||||
"rgb(15, 151, 136)",
|
||||
"rgb(39, 153, 79)",
|
||||
"rgb(119, 141, 17)",
|
||||
"rgb(167, 119, 12)",
|
||||
]
|
||||
balance = [
|
||||
"rgb(23, 28, 66)",
|
||||
"rgb(41, 58, 143)",
|
||||
"rgb(11, 102, 189)",
|
||||
"rgb(69, 144, 185)",
|
||||
"rgb(142, 181, 194)",
|
||||
"rgb(210, 216, 219)",
|
||||
"rgb(230, 210, 204)",
|
||||
"rgb(213, 157, 137)",
|
||||
"rgb(196, 101, 72)",
|
||||
"rgb(172, 43, 36)",
|
||||
"rgb(120, 14, 40)",
|
||||
"rgb(60, 9, 17)",
|
||||
]
|
||||
delta = [
|
||||
"rgb(16, 31, 63)",
|
||||
"rgb(38, 62, 144)",
|
||||
"rgb(30, 110, 161)",
|
||||
"rgb(60, 154, 171)",
|
||||
"rgb(140, 193, 186)",
|
||||
"rgb(217, 229, 218)",
|
||||
"rgb(239, 226, 156)",
|
||||
"rgb(195, 182, 59)",
|
||||
"rgb(115, 152, 5)",
|
||||
"rgb(34, 120, 36)",
|
||||
"rgb(18, 78, 43)",
|
||||
"rgb(23, 35, 18)",
|
||||
]
|
||||
curl = [
|
||||
"rgb(20, 29, 67)",
|
||||
"rgb(28, 72, 93)",
|
||||
"rgb(18, 115, 117)",
|
||||
"rgb(63, 156, 129)",
|
||||
"rgb(153, 189, 156)",
|
||||
"rgb(223, 225, 211)",
|
||||
"rgb(241, 218, 206)",
|
||||
"rgb(224, 160, 137)",
|
||||
"rgb(203, 101, 99)",
|
||||
"rgb(164, 54, 96)",
|
||||
"rgb(111, 23, 91)",
|
||||
"rgb(51, 13, 53)",
|
||||
]
|
||||
|
||||
algae_r = algae[::-1]
|
||||
amp_r = amp[::-1]
|
||||
balance_r = balance[::-1]
|
||||
curl_r = curl[::-1]
|
||||
deep_r = deep[::-1]
|
||||
delta_r = delta[::-1]
|
||||
dense_r = dense[::-1]
|
||||
gray_r = gray[::-1]
|
||||
haline_r = haline[::-1]
|
||||
ice_r = ice[::-1]
|
||||
matter_r = matter[::-1]
|
||||
oxy_r = oxy[::-1]
|
||||
phase_r = phase[::-1]
|
||||
solar_r = solar[::-1]
|
||||
speed_r = speed[::-1]
|
||||
tempo_r = tempo[::-1]
|
||||
thermal_r = thermal[::-1]
|
||||
turbid_r = turbid[::-1]
|
494
lib/python3.11/site-packages/_plotly_utils/colors/colorbrewer.py
Normal file
494
lib/python3.11/site-packages/_plotly_utils/colors/colorbrewer.py
Normal file
@ -0,0 +1,494 @@
|
||||
"""
|
||||
Color scales and sequences from the colorbrewer 2 project
|
||||
|
||||
Learn more at http://colorbrewer2.org
|
||||
|
||||
colorbrewer is made available under an Apache license: http://colorbrewer2.org/export/LICENSE.txt
|
||||
"""
|
||||
|
||||
from ._swatches import _swatches
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
BrBG = [
|
||||
"rgb(84,48,5)",
|
||||
"rgb(140,81,10)",
|
||||
"rgb(191,129,45)",
|
||||
"rgb(223,194,125)",
|
||||
"rgb(246,232,195)",
|
||||
"rgb(245,245,245)",
|
||||
"rgb(199,234,229)",
|
||||
"rgb(128,205,193)",
|
||||
"rgb(53,151,143)",
|
||||
"rgb(1,102,94)",
|
||||
"rgb(0,60,48)",
|
||||
]
|
||||
|
||||
PRGn = [
|
||||
"rgb(64,0,75)",
|
||||
"rgb(118,42,131)",
|
||||
"rgb(153,112,171)",
|
||||
"rgb(194,165,207)",
|
||||
"rgb(231,212,232)",
|
||||
"rgb(247,247,247)",
|
||||
"rgb(217,240,211)",
|
||||
"rgb(166,219,160)",
|
||||
"rgb(90,174,97)",
|
||||
"rgb(27,120,55)",
|
||||
"rgb(0,68,27)",
|
||||
]
|
||||
|
||||
PiYG = [
|
||||
"rgb(142,1,82)",
|
||||
"rgb(197,27,125)",
|
||||
"rgb(222,119,174)",
|
||||
"rgb(241,182,218)",
|
||||
"rgb(253,224,239)",
|
||||
"rgb(247,247,247)",
|
||||
"rgb(230,245,208)",
|
||||
"rgb(184,225,134)",
|
||||
"rgb(127,188,65)",
|
||||
"rgb(77,146,33)",
|
||||
"rgb(39,100,25)",
|
||||
]
|
||||
|
||||
PuOr = [
|
||||
"rgb(127,59,8)",
|
||||
"rgb(179,88,6)",
|
||||
"rgb(224,130,20)",
|
||||
"rgb(253,184,99)",
|
||||
"rgb(254,224,182)",
|
||||
"rgb(247,247,247)",
|
||||
"rgb(216,218,235)",
|
||||
"rgb(178,171,210)",
|
||||
"rgb(128,115,172)",
|
||||
"rgb(84,39,136)",
|
||||
"rgb(45,0,75)",
|
||||
]
|
||||
|
||||
RdBu = [
|
||||
"rgb(103,0,31)",
|
||||
"rgb(178,24,43)",
|
||||
"rgb(214,96,77)",
|
||||
"rgb(244,165,130)",
|
||||
"rgb(253,219,199)",
|
||||
"rgb(247,247,247)",
|
||||
"rgb(209,229,240)",
|
||||
"rgb(146,197,222)",
|
||||
"rgb(67,147,195)",
|
||||
"rgb(33,102,172)",
|
||||
"rgb(5,48,97)",
|
||||
]
|
||||
|
||||
RdGy = [
|
||||
"rgb(103,0,31)",
|
||||
"rgb(178,24,43)",
|
||||
"rgb(214,96,77)",
|
||||
"rgb(244,165,130)",
|
||||
"rgb(253,219,199)",
|
||||
"rgb(255,255,255)",
|
||||
"rgb(224,224,224)",
|
||||
"rgb(186,186,186)",
|
||||
"rgb(135,135,135)",
|
||||
"rgb(77,77,77)",
|
||||
"rgb(26,26,26)",
|
||||
]
|
||||
|
||||
RdYlBu = [
|
||||
"rgb(165,0,38)",
|
||||
"rgb(215,48,39)",
|
||||
"rgb(244,109,67)",
|
||||
"rgb(253,174,97)",
|
||||
"rgb(254,224,144)",
|
||||
"rgb(255,255,191)",
|
||||
"rgb(224,243,248)",
|
||||
"rgb(171,217,233)",
|
||||
"rgb(116,173,209)",
|
||||
"rgb(69,117,180)",
|
||||
"rgb(49,54,149)",
|
||||
]
|
||||
|
||||
RdYlGn = [
|
||||
"rgb(165,0,38)",
|
||||
"rgb(215,48,39)",
|
||||
"rgb(244,109,67)",
|
||||
"rgb(253,174,97)",
|
||||
"rgb(254,224,139)",
|
||||
"rgb(255,255,191)",
|
||||
"rgb(217,239,139)",
|
||||
"rgb(166,217,106)",
|
||||
"rgb(102,189,99)",
|
||||
"rgb(26,152,80)",
|
||||
"rgb(0,104,55)",
|
||||
]
|
||||
|
||||
Spectral = [
|
||||
"rgb(158,1,66)",
|
||||
"rgb(213,62,79)",
|
||||
"rgb(244,109,67)",
|
||||
"rgb(253,174,97)",
|
||||
"rgb(254,224,139)",
|
||||
"rgb(255,255,191)",
|
||||
"rgb(230,245,152)",
|
||||
"rgb(171,221,164)",
|
||||
"rgb(102,194,165)",
|
||||
"rgb(50,136,189)",
|
||||
"rgb(94,79,162)",
|
||||
]
|
||||
|
||||
Set1 = [
|
||||
"rgb(228,26,28)",
|
||||
"rgb(55,126,184)",
|
||||
"rgb(77,175,74)",
|
||||
"rgb(152,78,163)",
|
||||
"rgb(255,127,0)",
|
||||
"rgb(255,255,51)",
|
||||
"rgb(166,86,40)",
|
||||
"rgb(247,129,191)",
|
||||
"rgb(153,153,153)",
|
||||
]
|
||||
|
||||
|
||||
Pastel1 = [
|
||||
"rgb(251,180,174)",
|
||||
"rgb(179,205,227)",
|
||||
"rgb(204,235,197)",
|
||||
"rgb(222,203,228)",
|
||||
"rgb(254,217,166)",
|
||||
"rgb(255,255,204)",
|
||||
"rgb(229,216,189)",
|
||||
"rgb(253,218,236)",
|
||||
"rgb(242,242,242)",
|
||||
]
|
||||
Dark2 = [
|
||||
"rgb(27,158,119)",
|
||||
"rgb(217,95,2)",
|
||||
"rgb(117,112,179)",
|
||||
"rgb(231,41,138)",
|
||||
"rgb(102,166,30)",
|
||||
"rgb(230,171,2)",
|
||||
"rgb(166,118,29)",
|
||||
"rgb(102,102,102)",
|
||||
]
|
||||
Set2 = [
|
||||
"rgb(102,194,165)",
|
||||
"rgb(252,141,98)",
|
||||
"rgb(141,160,203)",
|
||||
"rgb(231,138,195)",
|
||||
"rgb(166,216,84)",
|
||||
"rgb(255,217,47)",
|
||||
"rgb(229,196,148)",
|
||||
"rgb(179,179,179)",
|
||||
]
|
||||
|
||||
|
||||
Pastel2 = [
|
||||
"rgb(179,226,205)",
|
||||
"rgb(253,205,172)",
|
||||
"rgb(203,213,232)",
|
||||
"rgb(244,202,228)",
|
||||
"rgb(230,245,201)",
|
||||
"rgb(255,242,174)",
|
||||
"rgb(241,226,204)",
|
||||
"rgb(204,204,204)",
|
||||
]
|
||||
|
||||
Set3 = [
|
||||
"rgb(141,211,199)",
|
||||
"rgb(255,255,179)",
|
||||
"rgb(190,186,218)",
|
||||
"rgb(251,128,114)",
|
||||
"rgb(128,177,211)",
|
||||
"rgb(253,180,98)",
|
||||
"rgb(179,222,105)",
|
||||
"rgb(252,205,229)",
|
||||
"rgb(217,217,217)",
|
||||
"rgb(188,128,189)",
|
||||
"rgb(204,235,197)",
|
||||
"rgb(255,237,111)",
|
||||
]
|
||||
|
||||
Accent = [
|
||||
"rgb(127,201,127)",
|
||||
"rgb(190,174,212)",
|
||||
"rgb(253,192,134)",
|
||||
"rgb(255,255,153)",
|
||||
"rgb(56,108,176)",
|
||||
"rgb(240,2,127)",
|
||||
"rgb(191,91,23)",
|
||||
"rgb(102,102,102)",
|
||||
]
|
||||
|
||||
|
||||
Paired = [
|
||||
"rgb(166,206,227)",
|
||||
"rgb(31,120,180)",
|
||||
"rgb(178,223,138)",
|
||||
"rgb(51,160,44)",
|
||||
"rgb(251,154,153)",
|
||||
"rgb(227,26,28)",
|
||||
"rgb(253,191,111)",
|
||||
"rgb(255,127,0)",
|
||||
"rgb(202,178,214)",
|
||||
"rgb(106,61,154)",
|
||||
"rgb(255,255,153)",
|
||||
"rgb(177,89,40)",
|
||||
]
|
||||
|
||||
|
||||
Blues = [
|
||||
"rgb(247,251,255)",
|
||||
"rgb(222,235,247)",
|
||||
"rgb(198,219,239)",
|
||||
"rgb(158,202,225)",
|
||||
"rgb(107,174,214)",
|
||||
"rgb(66,146,198)",
|
||||
"rgb(33,113,181)",
|
||||
"rgb(8,81,156)",
|
||||
"rgb(8,48,107)",
|
||||
]
|
||||
|
||||
BuGn = [
|
||||
"rgb(247,252,253)",
|
||||
"rgb(229,245,249)",
|
||||
"rgb(204,236,230)",
|
||||
"rgb(153,216,201)",
|
||||
"rgb(102,194,164)",
|
||||
"rgb(65,174,118)",
|
||||
"rgb(35,139,69)",
|
||||
"rgb(0,109,44)",
|
||||
"rgb(0,68,27)",
|
||||
]
|
||||
|
||||
BuPu = [
|
||||
"rgb(247,252,253)",
|
||||
"rgb(224,236,244)",
|
||||
"rgb(191,211,230)",
|
||||
"rgb(158,188,218)",
|
||||
"rgb(140,150,198)",
|
||||
"rgb(140,107,177)",
|
||||
"rgb(136,65,157)",
|
||||
"rgb(129,15,124)",
|
||||
"rgb(77,0,75)",
|
||||
]
|
||||
|
||||
GnBu = [
|
||||
"rgb(247,252,240)",
|
||||
"rgb(224,243,219)",
|
||||
"rgb(204,235,197)",
|
||||
"rgb(168,221,181)",
|
||||
"rgb(123,204,196)",
|
||||
"rgb(78,179,211)",
|
||||
"rgb(43,140,190)",
|
||||
"rgb(8,104,172)",
|
||||
"rgb(8,64,129)",
|
||||
]
|
||||
|
||||
Greens = [
|
||||
"rgb(247,252,245)",
|
||||
"rgb(229,245,224)",
|
||||
"rgb(199,233,192)",
|
||||
"rgb(161,217,155)",
|
||||
"rgb(116,196,118)",
|
||||
"rgb(65,171,93)",
|
||||
"rgb(35,139,69)",
|
||||
"rgb(0,109,44)",
|
||||
"rgb(0,68,27)",
|
||||
]
|
||||
|
||||
Greys = [
|
||||
"rgb(255,255,255)",
|
||||
"rgb(240,240,240)",
|
||||
"rgb(217,217,217)",
|
||||
"rgb(189,189,189)",
|
||||
"rgb(150,150,150)",
|
||||
"rgb(115,115,115)",
|
||||
"rgb(82,82,82)",
|
||||
"rgb(37,37,37)",
|
||||
"rgb(0,0,0)",
|
||||
]
|
||||
|
||||
OrRd = [
|
||||
"rgb(255,247,236)",
|
||||
"rgb(254,232,200)",
|
||||
"rgb(253,212,158)",
|
||||
"rgb(253,187,132)",
|
||||
"rgb(252,141,89)",
|
||||
"rgb(239,101,72)",
|
||||
"rgb(215,48,31)",
|
||||
"rgb(179,0,0)",
|
||||
"rgb(127,0,0)",
|
||||
]
|
||||
|
||||
Oranges = [
|
||||
"rgb(255,245,235)",
|
||||
"rgb(254,230,206)",
|
||||
"rgb(253,208,162)",
|
||||
"rgb(253,174,107)",
|
||||
"rgb(253,141,60)",
|
||||
"rgb(241,105,19)",
|
||||
"rgb(217,72,1)",
|
||||
"rgb(166,54,3)",
|
||||
"rgb(127,39,4)",
|
||||
]
|
||||
|
||||
PuBu = [
|
||||
"rgb(255,247,251)",
|
||||
"rgb(236,231,242)",
|
||||
"rgb(208,209,230)",
|
||||
"rgb(166,189,219)",
|
||||
"rgb(116,169,207)",
|
||||
"rgb(54,144,192)",
|
||||
"rgb(5,112,176)",
|
||||
"rgb(4,90,141)",
|
||||
"rgb(2,56,88)",
|
||||
]
|
||||
|
||||
PuBuGn = [
|
||||
"rgb(255,247,251)",
|
||||
"rgb(236,226,240)",
|
||||
"rgb(208,209,230)",
|
||||
"rgb(166,189,219)",
|
||||
"rgb(103,169,207)",
|
||||
"rgb(54,144,192)",
|
||||
"rgb(2,129,138)",
|
||||
"rgb(1,108,89)",
|
||||
"rgb(1,70,54)",
|
||||
]
|
||||
|
||||
PuRd = [
|
||||
"rgb(247,244,249)",
|
||||
"rgb(231,225,239)",
|
||||
"rgb(212,185,218)",
|
||||
"rgb(201,148,199)",
|
||||
"rgb(223,101,176)",
|
||||
"rgb(231,41,138)",
|
||||
"rgb(206,18,86)",
|
||||
"rgb(152,0,67)",
|
||||
"rgb(103,0,31)",
|
||||
]
|
||||
|
||||
Purples = [
|
||||
"rgb(252,251,253)",
|
||||
"rgb(239,237,245)",
|
||||
"rgb(218,218,235)",
|
||||
"rgb(188,189,220)",
|
||||
"rgb(158,154,200)",
|
||||
"rgb(128,125,186)",
|
||||
"rgb(106,81,163)",
|
||||
"rgb(84,39,143)",
|
||||
"rgb(63,0,125)",
|
||||
]
|
||||
|
||||
RdPu = [
|
||||
"rgb(255,247,243)",
|
||||
"rgb(253,224,221)",
|
||||
"rgb(252,197,192)",
|
||||
"rgb(250,159,181)",
|
||||
"rgb(247,104,161)",
|
||||
"rgb(221,52,151)",
|
||||
"rgb(174,1,126)",
|
||||
"rgb(122,1,119)",
|
||||
"rgb(73,0,106)",
|
||||
]
|
||||
|
||||
Reds = [
|
||||
"rgb(255,245,240)",
|
||||
"rgb(254,224,210)",
|
||||
"rgb(252,187,161)",
|
||||
"rgb(252,146,114)",
|
||||
"rgb(251,106,74)",
|
||||
"rgb(239,59,44)",
|
||||
"rgb(203,24,29)",
|
||||
"rgb(165,15,21)",
|
||||
"rgb(103,0,13)",
|
||||
]
|
||||
|
||||
YlGn = [
|
||||
"rgb(255,255,229)",
|
||||
"rgb(247,252,185)",
|
||||
"rgb(217,240,163)",
|
||||
"rgb(173,221,142)",
|
||||
"rgb(120,198,121)",
|
||||
"rgb(65,171,93)",
|
||||
"rgb(35,132,67)",
|
||||
"rgb(0,104,55)",
|
||||
"rgb(0,69,41)",
|
||||
]
|
||||
|
||||
YlGnBu = [
|
||||
"rgb(255,255,217)",
|
||||
"rgb(237,248,177)",
|
||||
"rgb(199,233,180)",
|
||||
"rgb(127,205,187)",
|
||||
"rgb(65,182,196)",
|
||||
"rgb(29,145,192)",
|
||||
"rgb(34,94,168)",
|
||||
"rgb(37,52,148)",
|
||||
"rgb(8,29,88)",
|
||||
]
|
||||
|
||||
YlOrBr = [
|
||||
"rgb(255,255,229)",
|
||||
"rgb(255,247,188)",
|
||||
"rgb(254,227,145)",
|
||||
"rgb(254,196,79)",
|
||||
"rgb(254,153,41)",
|
||||
"rgb(236,112,20)",
|
||||
"rgb(204,76,2)",
|
||||
"rgb(153,52,4)",
|
||||
"rgb(102,37,6)",
|
||||
]
|
||||
|
||||
YlOrRd = [
|
||||
"rgb(255,255,204)",
|
||||
"rgb(255,237,160)",
|
||||
"rgb(254,217,118)",
|
||||
"rgb(254,178,76)",
|
||||
"rgb(253,141,60)",
|
||||
"rgb(252,78,42)",
|
||||
"rgb(227,26,28)",
|
||||
"rgb(189,0,38)",
|
||||
"rgb(128,0,38)",
|
||||
]
|
||||
|
||||
Accent_r = Accent[::-1]
|
||||
Blues_r = Blues[::-1]
|
||||
BrBG_r = BrBG[::-1]
|
||||
BuGn_r = BuGn[::-1]
|
||||
BuPu_r = BuPu[::-1]
|
||||
Dark2_r = Dark2[::-1]
|
||||
GnBu_r = GnBu[::-1]
|
||||
Greens_r = Greens[::-1]
|
||||
Greys_r = Greys[::-1]
|
||||
OrRd_r = OrRd[::-1]
|
||||
Oranges_r = Oranges[::-1]
|
||||
PRGn_r = PRGn[::-1]
|
||||
Paired_r = Paired[::-1]
|
||||
Pastel1_r = Pastel1[::-1]
|
||||
Pastel2_r = Pastel2[::-1]
|
||||
PiYG_r = PiYG[::-1]
|
||||
PuBu_r = PuBu[::-1]
|
||||
PuBuGn_r = PuBuGn[::-1]
|
||||
PuOr_r = PuOr[::-1]
|
||||
PuRd_r = PuRd[::-1]
|
||||
Purples_r = Purples[::-1]
|
||||
RdBu_r = RdBu[::-1]
|
||||
RdGy_r = RdGy[::-1]
|
||||
RdPu_r = RdPu[::-1]
|
||||
RdYlBu_r = RdYlBu[::-1]
|
||||
RdYlGn_r = RdYlGn[::-1]
|
||||
Reds_r = Reds[::-1]
|
||||
Set1_r = Set1[::-1]
|
||||
Set2_r = Set2[::-1]
|
||||
Set3_r = Set3[::-1]
|
||||
Spectral_r = Spectral[::-1]
|
||||
YlGn_r = YlGn[::-1]
|
||||
YlGnBu_r = YlGnBu[::-1]
|
||||
YlOrBr_r = YlOrBr[::-1]
|
||||
YlOrRd_r = YlOrRd[::-1]
|
157
lib/python3.11/site-packages/_plotly_utils/colors/cyclical.py
Normal file
157
lib/python3.11/site-packages/_plotly_utils/colors/cyclical.py
Normal file
@ -0,0 +1,157 @@
|
||||
"""
|
||||
Cyclical color scales are appropriate for continuous data that has a natural cyclical \
|
||||
structure, such as temporal data (hour of day, day of week, day of year, seasons) or
|
||||
complex numbers or other phase data.
|
||||
"""
|
||||
|
||||
from ._swatches import _swatches, _swatches_continuous, _swatches_cyclical
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
|
||||
def swatches_continuous(template=None):
|
||||
return _swatches_continuous(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches_continuous.__doc__ = _swatches_continuous.__doc__
|
||||
|
||||
|
||||
def swatches_cyclical(template=None):
|
||||
return _swatches_cyclical(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches_cyclical.__doc__ = _swatches_cyclical.__doc__
|
||||
|
||||
|
||||
Twilight = [
|
||||
"#e2d9e2",
|
||||
"#9ebbc9",
|
||||
"#6785be",
|
||||
"#5e43a5",
|
||||
"#421257",
|
||||
"#471340",
|
||||
"#8e2c50",
|
||||
"#ba6657",
|
||||
"#ceac94",
|
||||
"#e2d9e2",
|
||||
]
|
||||
IceFire = [
|
||||
"#000000",
|
||||
"#001f4d",
|
||||
"#003786",
|
||||
"#0e58a8",
|
||||
"#217eb8",
|
||||
"#30a4ca",
|
||||
"#54c8df",
|
||||
"#9be4ef",
|
||||
"#e1e9d1",
|
||||
"#f3d573",
|
||||
"#e7b000",
|
||||
"#da8200",
|
||||
"#c65400",
|
||||
"#ac2301",
|
||||
"#820000",
|
||||
"#4c0000",
|
||||
"#000000",
|
||||
]
|
||||
Edge = [
|
||||
"#313131",
|
||||
"#3d019d",
|
||||
"#3810dc",
|
||||
"#2d47f9",
|
||||
"#2593ff",
|
||||
"#2adef6",
|
||||
"#60fdfa",
|
||||
"#aefdff",
|
||||
"#f3f3f1",
|
||||
"#fffda9",
|
||||
"#fafd5b",
|
||||
"#f7da29",
|
||||
"#ff8e25",
|
||||
"#f8432d",
|
||||
"#d90d39",
|
||||
"#97023d",
|
||||
"#313131",
|
||||
]
|
||||
Phase = [
|
||||
"rgb(167, 119, 12)",
|
||||
"rgb(197, 96, 51)",
|
||||
"rgb(217, 67, 96)",
|
||||
"rgb(221, 38, 163)",
|
||||
"rgb(196, 59, 224)",
|
||||
"rgb(153, 97, 244)",
|
||||
"rgb(95, 127, 228)",
|
||||
"rgb(40, 144, 183)",
|
||||
"rgb(15, 151, 136)",
|
||||
"rgb(39, 153, 79)",
|
||||
"rgb(119, 141, 17)",
|
||||
"rgb(167, 119, 12)",
|
||||
]
|
||||
HSV = [
|
||||
"#ff0000",
|
||||
"#ffa700",
|
||||
"#afff00",
|
||||
"#08ff00",
|
||||
"#00ff9f",
|
||||
"#00b7ff",
|
||||
"#0010ff",
|
||||
"#9700ff",
|
||||
"#ff00bf",
|
||||
"#ff0000",
|
||||
]
|
||||
mrybm = [
|
||||
"#f884f7",
|
||||
"#f968c4",
|
||||
"#ea4388",
|
||||
"#cf244b",
|
||||
"#b51a15",
|
||||
"#bd4304",
|
||||
"#cc6904",
|
||||
"#d58f04",
|
||||
"#cfaa27",
|
||||
"#a19f62",
|
||||
"#588a93",
|
||||
"#2269c4",
|
||||
"#3e3ef0",
|
||||
"#6b4ef9",
|
||||
"#956bfa",
|
||||
"#cd7dfe",
|
||||
"#f884f7",
|
||||
]
|
||||
mygbm = [
|
||||
"#ef55f1",
|
||||
"#fb84ce",
|
||||
"#fbafa1",
|
||||
"#fcd471",
|
||||
"#f0ed35",
|
||||
"#c6e516",
|
||||
"#96d310",
|
||||
"#61c10b",
|
||||
"#31ac28",
|
||||
"#439064",
|
||||
"#3d719a",
|
||||
"#284ec8",
|
||||
"#2e21ea",
|
||||
"#6324f5",
|
||||
"#9139fa",
|
||||
"#c543fa",
|
||||
"#ef55f1",
|
||||
]
|
||||
|
||||
Edge_r = Edge[::-1]
|
||||
HSV_r = HSV[::-1]
|
||||
IceFire_r = IceFire[::-1]
|
||||
Phase_r = Phase[::-1]
|
||||
Twilight_r = Twilight[::-1]
|
||||
mrybm_r = mrybm[::-1]
|
||||
mygbm_r = mygbm[::-1]
|
||||
|
||||
__all__ = [
|
||||
"swatches",
|
||||
"swatches_cyclical",
|
||||
]
|
@ -0,0 +1,75 @@
|
||||
"""
|
||||
Diverging color scales are appropriate for continuous data that has a natural midpoint \
|
||||
other otherwise informative special value, such as 0 altitude, or the boiling point
|
||||
of a liquid. The color scales in this module are \
|
||||
mostly meant to be passed in as the `color_continuous_scale` argument to various \
|
||||
functions, and to be used with the `color_continuous_midpoint` argument.
|
||||
"""
|
||||
|
||||
from .colorbrewer import ( # noqa: F401
|
||||
BrBG,
|
||||
PRGn,
|
||||
PiYG,
|
||||
PuOr,
|
||||
RdBu,
|
||||
RdGy,
|
||||
RdYlBu,
|
||||
RdYlGn,
|
||||
Spectral,
|
||||
BrBG_r,
|
||||
PRGn_r,
|
||||
PiYG_r,
|
||||
PuOr_r,
|
||||
RdBu_r,
|
||||
RdGy_r,
|
||||
RdYlBu_r,
|
||||
RdYlGn_r,
|
||||
Spectral_r,
|
||||
)
|
||||
from .cmocean import ( # noqa: F401
|
||||
balance,
|
||||
delta,
|
||||
curl,
|
||||
oxy,
|
||||
balance_r,
|
||||
delta_r,
|
||||
curl_r,
|
||||
oxy_r,
|
||||
)
|
||||
from .carto import ( # noqa: F401
|
||||
Armyrose,
|
||||
Fall,
|
||||
Geyser,
|
||||
Temps,
|
||||
Tealrose,
|
||||
Tropic,
|
||||
Earth,
|
||||
Armyrose_r,
|
||||
Fall_r,
|
||||
Geyser_r,
|
||||
Temps_r,
|
||||
Tealrose_r,
|
||||
Tropic_r,
|
||||
Earth_r,
|
||||
)
|
||||
|
||||
from .plotlyjs import Picnic, Portland, Picnic_r, Portland_r # noqa: F401
|
||||
|
||||
from ._swatches import _swatches, _swatches_continuous
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
|
||||
def swatches_continuous(template=None):
|
||||
return _swatches_continuous(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches_continuous.__doc__ = _swatches_continuous.__doc__
|
||||
|
||||
|
||||
__all__ = ["swatches"]
|
180
lib/python3.11/site-packages/_plotly_utils/colors/plotlyjs.py
Normal file
180
lib/python3.11/site-packages/_plotly_utils/colors/plotlyjs.py
Normal file
@ -0,0 +1,180 @@
|
||||
# Copied from
|
||||
# https://github.com/plotly/plotly.js/blob/master/src/components/colorscale/scales.js
|
||||
|
||||
# NOTE: these differ slightly from plotly.colors.PLOTLY_SCALES from Plotly.js because
|
||||
# those ones don't have perfectly evenly spaced steps ...
|
||||
# not sure when this skew was introduced, possibly as early as Plotly.py v4.0
|
||||
|
||||
Blackbody = [
|
||||
"rgb(0,0,0)",
|
||||
"rgb(230,0,0)",
|
||||
"rgb(230,210,0)",
|
||||
"rgb(255,255,255)",
|
||||
"rgb(160,200,255)",
|
||||
]
|
||||
Bluered = ["rgb(0,0,255)", "rgb(255,0,0)"]
|
||||
Blues = [
|
||||
"rgb(5,10,172)",
|
||||
"rgb(40,60,190)",
|
||||
"rgb(70,100,245)",
|
||||
"rgb(90,120,245)",
|
||||
"rgb(106,137,247)",
|
||||
"rgb(220,220,220)",
|
||||
]
|
||||
Cividis = [
|
||||
"rgb(0,32,76)",
|
||||
"rgb(0,42,102)",
|
||||
"rgb(0,52,110)",
|
||||
"rgb(39,63,108)",
|
||||
"rgb(60,74,107)",
|
||||
"rgb(76,85,107)",
|
||||
"rgb(91,95,109)",
|
||||
"rgb(104,106,112)",
|
||||
"rgb(117,117,117)",
|
||||
"rgb(131,129,120)",
|
||||
"rgb(146,140,120)",
|
||||
"rgb(161,152,118)",
|
||||
"rgb(176,165,114)",
|
||||
"rgb(192,177,109)",
|
||||
"rgb(209,191,102)",
|
||||
"rgb(225,204,92)",
|
||||
"rgb(243,219,79)",
|
||||
"rgb(255,233,69)",
|
||||
]
|
||||
Earth = [
|
||||
"rgb(0,0,130)",
|
||||
"rgb(0,180,180)",
|
||||
"rgb(40,210,40)",
|
||||
"rgb(230,230,50)",
|
||||
"rgb(120,70,20)",
|
||||
"rgb(255,255,255)",
|
||||
]
|
||||
Electric = [
|
||||
"rgb(0,0,0)",
|
||||
"rgb(30,0,100)",
|
||||
"rgb(120,0,100)",
|
||||
"rgb(160,90,0)",
|
||||
"rgb(230,200,0)",
|
||||
"rgb(255,250,220)",
|
||||
]
|
||||
Greens = [
|
||||
"rgb(0,68,27)",
|
||||
"rgb(0,109,44)",
|
||||
"rgb(35,139,69)",
|
||||
"rgb(65,171,93)",
|
||||
"rgb(116,196,118)",
|
||||
"rgb(161,217,155)",
|
||||
"rgb(199,233,192)",
|
||||
"rgb(229,245,224)",
|
||||
"rgb(247,252,245)",
|
||||
]
|
||||
Greys = ["rgb(0,0,0)", "rgb(255,255,255)"]
|
||||
Hot = ["rgb(0,0,0)", "rgb(230,0,0)", "rgb(255,210,0)", "rgb(255,255,255)"]
|
||||
Jet = [
|
||||
"rgb(0,0,131)",
|
||||
"rgb(0,60,170)",
|
||||
"rgb(5,255,255)",
|
||||
"rgb(255,255,0)",
|
||||
"rgb(250,0,0)",
|
||||
"rgb(128,0,0)",
|
||||
]
|
||||
Picnic = [
|
||||
"rgb(0,0,255)",
|
||||
"rgb(51,153,255)",
|
||||
"rgb(102,204,255)",
|
||||
"rgb(153,204,255)",
|
||||
"rgb(204,204,255)",
|
||||
"rgb(255,255,255)",
|
||||
"rgb(255,204,255)",
|
||||
"rgb(255,153,255)",
|
||||
"rgb(255,102,204)",
|
||||
"rgb(255,102,102)",
|
||||
"rgb(255,0,0)",
|
||||
]
|
||||
Portland = [
|
||||
"rgb(12,51,131)",
|
||||
"rgb(10,136,186)",
|
||||
"rgb(242,211,56)",
|
||||
"rgb(242,143,56)",
|
||||
"rgb(217,30,30)",
|
||||
]
|
||||
Rainbow = [
|
||||
"rgb(150,0,90)",
|
||||
"rgb(0,0,200)",
|
||||
"rgb(0,25,255)",
|
||||
"rgb(0,152,255)",
|
||||
"rgb(44,255,150)",
|
||||
"rgb(151,255,0)",
|
||||
"rgb(255,234,0)",
|
||||
"rgb(255,111,0)",
|
||||
"rgb(255,0,0)",
|
||||
]
|
||||
RdBu = [
|
||||
"rgb(5,10,172)",
|
||||
"rgb(106,137,247)",
|
||||
"rgb(190,190,190)",
|
||||
"rgb(220,170,132)",
|
||||
"rgb(230,145,90)",
|
||||
"rgb(178,10,28)",
|
||||
]
|
||||
Reds = ["rgb(220,220,220)", "rgb(245,195,157)", "rgb(245,160,105)", "rgb(178,10,28)"]
|
||||
Viridis = [
|
||||
"#440154",
|
||||
"#48186a",
|
||||
"#472d7b",
|
||||
"#424086",
|
||||
"#3b528b",
|
||||
"#33638d",
|
||||
"#2c728e",
|
||||
"#26828e",
|
||||
"#21918c",
|
||||
"#1fa088",
|
||||
"#28ae80",
|
||||
"#3fbc73",
|
||||
"#5ec962",
|
||||
"#84d44b",
|
||||
"#addc30",
|
||||
"#d8e219",
|
||||
"#fde725",
|
||||
]
|
||||
YlGnBu = [
|
||||
"rgb(8,29,88)",
|
||||
"rgb(37,52,148)",
|
||||
"rgb(34,94,168)",
|
||||
"rgb(29,145,192)",
|
||||
"rgb(65,182,196)",
|
||||
"rgb(127,205,187)",
|
||||
"rgb(199,233,180)",
|
||||
"rgb(237,248,217)",
|
||||
"rgb(255,255,217)",
|
||||
]
|
||||
YlOrRd = [
|
||||
"rgb(128,0,38)",
|
||||
"rgb(189,0,38)",
|
||||
"rgb(227,26,28)",
|
||||
"rgb(252,78,42)",
|
||||
"rgb(253,141,60)",
|
||||
"rgb(254,178,76)",
|
||||
"rgb(254,217,118)",
|
||||
"rgb(255,237,160)",
|
||||
"rgb(255,255,204)",
|
||||
]
|
||||
|
||||
Blackbody_r = Blackbody[::-1]
|
||||
Bluered_r = Bluered[::-1]
|
||||
Blues_r = Blues[::-1]
|
||||
Cividis_r = Cividis[::-1]
|
||||
Earth_r = Earth[::-1]
|
||||
Electric_r = Electric[::-1]
|
||||
Greens_r = Greens[::-1]
|
||||
Greys_r = Greys[::-1]
|
||||
Hot_r = Hot[::-1]
|
||||
Jet_r = Jet[::-1]
|
||||
Picnic_r = Picnic[::-1]
|
||||
Portland_r = Portland[::-1]
|
||||
Rainbow_r = Rainbow[::-1]
|
||||
RdBu_r = RdBu[::-1]
|
||||
Reds_r = Reds[::-1]
|
||||
Viridis_r = Viridis[::-1]
|
||||
YlGnBu_r = YlGnBu[::-1]
|
||||
YlOrRd_r = YlOrRd[::-1]
|
184
lib/python3.11/site-packages/_plotly_utils/colors/qualitative.py
Normal file
184
lib/python3.11/site-packages/_plotly_utils/colors/qualitative.py
Normal file
@ -0,0 +1,184 @@
|
||||
"""
|
||||
Qualitative color sequences are appropriate for data that has no natural ordering, such \
|
||||
as categories, colors, names, countries etc. The color sequences in this module are \
|
||||
mostly meant to be passed in as the `color_discrete_sequence` argument to various functions.
|
||||
"""
|
||||
|
||||
from ._swatches import _swatches
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
Plotly = [
|
||||
"#636EFA",
|
||||
"#EF553B",
|
||||
"#00CC96",
|
||||
"#AB63FA",
|
||||
"#FFA15A",
|
||||
"#19D3F3",
|
||||
"#FF6692",
|
||||
"#B6E880",
|
||||
"#FF97FF",
|
||||
"#FECB52",
|
||||
]
|
||||
|
||||
D3 = [
|
||||
"#1F77B4",
|
||||
"#FF7F0E",
|
||||
"#2CA02C",
|
||||
"#D62728",
|
||||
"#9467BD",
|
||||
"#8C564B",
|
||||
"#E377C2",
|
||||
"#7F7F7F",
|
||||
"#BCBD22",
|
||||
"#17BECF",
|
||||
]
|
||||
G10 = [
|
||||
"#3366CC",
|
||||
"#DC3912",
|
||||
"#FF9900",
|
||||
"#109618",
|
||||
"#990099",
|
||||
"#0099C6",
|
||||
"#DD4477",
|
||||
"#66AA00",
|
||||
"#B82E2E",
|
||||
"#316395",
|
||||
]
|
||||
T10 = [
|
||||
"#4C78A8",
|
||||
"#F58518",
|
||||
"#E45756",
|
||||
"#72B7B2",
|
||||
"#54A24B",
|
||||
"#EECA3B",
|
||||
"#B279A2",
|
||||
"#FF9DA6",
|
||||
"#9D755D",
|
||||
"#BAB0AC",
|
||||
]
|
||||
Alphabet = [
|
||||
"#AA0DFE",
|
||||
"#3283FE",
|
||||
"#85660D",
|
||||
"#782AB6",
|
||||
"#565656",
|
||||
"#1C8356",
|
||||
"#16FF32",
|
||||
"#F7E1A0",
|
||||
"#E2E2E2",
|
||||
"#1CBE4F",
|
||||
"#C4451C",
|
||||
"#DEA0FD",
|
||||
"#FE00FA",
|
||||
"#325A9B",
|
||||
"#FEAF16",
|
||||
"#F8A19F",
|
||||
"#90AD1C",
|
||||
"#F6222E",
|
||||
"#1CFFCE",
|
||||
"#2ED9FF",
|
||||
"#B10DA1",
|
||||
"#C075A6",
|
||||
"#FC1CBF",
|
||||
"#B00068",
|
||||
"#FBE426",
|
||||
"#FA0087",
|
||||
]
|
||||
Dark24 = [
|
||||
"#2E91E5",
|
||||
"#E15F99",
|
||||
"#1CA71C",
|
||||
"#FB0D0D",
|
||||
"#DA16FF",
|
||||
"#222A2A",
|
||||
"#B68100",
|
||||
"#750D86",
|
||||
"#EB663B",
|
||||
"#511CFB",
|
||||
"#00A08B",
|
||||
"#FB00D1",
|
||||
"#FC0080",
|
||||
"#B2828D",
|
||||
"#6C7C32",
|
||||
"#778AAE",
|
||||
"#862A16",
|
||||
"#A777F1",
|
||||
"#620042",
|
||||
"#1616A7",
|
||||
"#DA60CA",
|
||||
"#6C4516",
|
||||
"#0D2A63",
|
||||
"#AF0038",
|
||||
]
|
||||
Light24 = [
|
||||
"#FD3216",
|
||||
"#00FE35",
|
||||
"#6A76FC",
|
||||
"#FED4C4",
|
||||
"#FE00CE",
|
||||
"#0DF9FF",
|
||||
"#F6F926",
|
||||
"#FF9616",
|
||||
"#479B55",
|
||||
"#EEA6FB",
|
||||
"#DC587D",
|
||||
"#D626FF",
|
||||
"#6E899C",
|
||||
"#00B5F7",
|
||||
"#B68E00",
|
||||
"#C9FBE5",
|
||||
"#FF0092",
|
||||
"#22FFA7",
|
||||
"#E3EE9E",
|
||||
"#86CE00",
|
||||
"#BC7196",
|
||||
"#7E7DCD",
|
||||
"#FC6955",
|
||||
"#E48F72",
|
||||
]
|
||||
|
||||
Alphabet_r = Alphabet[::-1]
|
||||
D3_r = D3[::-1]
|
||||
Dark24_r = Dark24[::-1]
|
||||
G10_r = G10[::-1]
|
||||
Light24_r = Light24[::-1]
|
||||
Plotly_r = Plotly[::-1]
|
||||
T10_r = T10[::-1]
|
||||
|
||||
from .colorbrewer import ( # noqa: E402 F401
|
||||
Set1,
|
||||
Pastel1,
|
||||
Dark2,
|
||||
Set2,
|
||||
Pastel2,
|
||||
Set3,
|
||||
Set1_r,
|
||||
Pastel1_r,
|
||||
Dark2_r,
|
||||
Set2_r,
|
||||
Pastel2_r,
|
||||
Set3_r,
|
||||
)
|
||||
from .carto import ( # noqa: E402 F401
|
||||
Antique,
|
||||
Bold,
|
||||
Pastel,
|
||||
Prism,
|
||||
Safe,
|
||||
Vivid,
|
||||
Antique_r,
|
||||
Bold_r,
|
||||
Pastel_r,
|
||||
Prism_r,
|
||||
Safe_r,
|
||||
Vivid_r,
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["swatches"]
|
257
lib/python3.11/site-packages/_plotly_utils/colors/sequential.py
Normal file
257
lib/python3.11/site-packages/_plotly_utils/colors/sequential.py
Normal file
@ -0,0 +1,257 @@
|
||||
"""
|
||||
Sequential color scales are appropriate for most continuous data, but in some cases it \
|
||||
can be helpful to use a `plotly.colors.diverging` or \
|
||||
`plotly.colors.cyclical` scale instead. The color scales in this module are \
|
||||
mostly meant to be passed in as the `color_continuous_scale` argument to various functions.
|
||||
"""
|
||||
|
||||
from ._swatches import _swatches, _swatches_continuous
|
||||
|
||||
|
||||
def swatches(template=None):
|
||||
return _swatches(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches.__doc__ = _swatches.__doc__
|
||||
|
||||
|
||||
def swatches_continuous(template=None):
|
||||
return _swatches_continuous(__name__, globals(), template)
|
||||
|
||||
|
||||
swatches_continuous.__doc__ = _swatches_continuous.__doc__
|
||||
|
||||
Plotly3 = [
|
||||
"#0508b8",
|
||||
"#1910d8",
|
||||
"#3c19f0",
|
||||
"#6b1cfb",
|
||||
"#981cfd",
|
||||
"#bf1cfd",
|
||||
"#dd2bfd",
|
||||
"#f246fe",
|
||||
"#fc67fd",
|
||||
"#fe88fc",
|
||||
"#fea5fd",
|
||||
"#febefe",
|
||||
"#fec3fe",
|
||||
]
|
||||
|
||||
Viridis = [
|
||||
"#440154",
|
||||
"#482878",
|
||||
"#3e4989",
|
||||
"#31688e",
|
||||
"#26828e",
|
||||
"#1f9e89",
|
||||
"#35b779",
|
||||
"#6ece58",
|
||||
"#b5de2b",
|
||||
"#fde725",
|
||||
]
|
||||
Cividis = [
|
||||
"#00224e",
|
||||
"#123570",
|
||||
"#3b496c",
|
||||
"#575d6d",
|
||||
"#707173",
|
||||
"#8a8678",
|
||||
"#a59c74",
|
||||
"#c3b369",
|
||||
"#e1cc55",
|
||||
"#fee838",
|
||||
]
|
||||
|
||||
Inferno = [
|
||||
"#000004",
|
||||
"#1b0c41",
|
||||
"#4a0c6b",
|
||||
"#781c6d",
|
||||
"#a52c60",
|
||||
"#cf4446",
|
||||
"#ed6925",
|
||||
"#fb9b06",
|
||||
"#f7d13d",
|
||||
"#fcffa4",
|
||||
]
|
||||
Magma = [
|
||||
"#000004",
|
||||
"#180f3d",
|
||||
"#440f76",
|
||||
"#721f81",
|
||||
"#9e2f7f",
|
||||
"#cd4071",
|
||||
"#f1605d",
|
||||
"#fd9668",
|
||||
"#feca8d",
|
||||
"#fcfdbf",
|
||||
]
|
||||
Plasma = [
|
||||
"#0d0887",
|
||||
"#46039f",
|
||||
"#7201a8",
|
||||
"#9c179e",
|
||||
"#bd3786",
|
||||
"#d8576b",
|
||||
"#ed7953",
|
||||
"#fb9f3a",
|
||||
"#fdca26",
|
||||
"#f0f921",
|
||||
]
|
||||
Turbo = [
|
||||
"#30123b",
|
||||
"#4145ab",
|
||||
"#4675ed",
|
||||
"#39a2fc",
|
||||
"#1bcfd4",
|
||||
"#24eca6",
|
||||
"#61fc6c",
|
||||
"#a4fc3b",
|
||||
"#d1e834",
|
||||
"#f3c63a",
|
||||
"#fe9b2d",
|
||||
"#f36315",
|
||||
"#d93806",
|
||||
"#b11901",
|
||||
"#7a0402",
|
||||
]
|
||||
|
||||
Cividis_r = Cividis[::-1]
|
||||
Inferno_r = Inferno[::-1]
|
||||
Magma_r = Magma[::-1]
|
||||
Plasma_r = Plasma[::-1]
|
||||
Plotly3_r = Plotly3[::-1]
|
||||
Turbo_r = Turbo[::-1]
|
||||
Viridis_r = Viridis[::-1]
|
||||
|
||||
from .plotlyjs import ( # noqa: E402 F401
|
||||
Blackbody,
|
||||
Bluered,
|
||||
Electric,
|
||||
Hot,
|
||||
Jet,
|
||||
Rainbow,
|
||||
Blackbody_r,
|
||||
Bluered_r,
|
||||
Electric_r,
|
||||
Hot_r,
|
||||
Jet_r,
|
||||
Rainbow_r,
|
||||
)
|
||||
|
||||
from .colorbrewer import ( # noqa: E402 F401
|
||||
Blues,
|
||||
BuGn,
|
||||
BuPu,
|
||||
GnBu,
|
||||
Greens,
|
||||
Greys,
|
||||
OrRd,
|
||||
Oranges,
|
||||
PuBu,
|
||||
PuBuGn,
|
||||
PuRd,
|
||||
Purples,
|
||||
RdBu,
|
||||
RdPu,
|
||||
Reds,
|
||||
YlGn,
|
||||
YlGnBu,
|
||||
YlOrBr,
|
||||
YlOrRd,
|
||||
Blues_r,
|
||||
BuGn_r,
|
||||
BuPu_r,
|
||||
GnBu_r,
|
||||
Greens_r,
|
||||
Greys_r,
|
||||
OrRd_r,
|
||||
Oranges_r,
|
||||
PuBu_r,
|
||||
PuBuGn_r,
|
||||
PuRd_r,
|
||||
Purples_r,
|
||||
RdBu_r,
|
||||
RdPu_r,
|
||||
Reds_r,
|
||||
YlGn_r,
|
||||
YlGnBu_r,
|
||||
YlOrBr_r,
|
||||
YlOrRd_r,
|
||||
)
|
||||
|
||||
from .cmocean import ( # noqa: E402 F401
|
||||
turbid,
|
||||
thermal,
|
||||
haline,
|
||||
solar,
|
||||
ice,
|
||||
gray,
|
||||
deep,
|
||||
dense,
|
||||
algae,
|
||||
matter,
|
||||
speed,
|
||||
amp,
|
||||
tempo,
|
||||
turbid_r,
|
||||
thermal_r,
|
||||
haline_r,
|
||||
solar_r,
|
||||
ice_r,
|
||||
gray_r,
|
||||
deep_r,
|
||||
dense_r,
|
||||
algae_r,
|
||||
matter_r,
|
||||
speed_r,
|
||||
amp_r,
|
||||
tempo_r,
|
||||
)
|
||||
|
||||
from .carto import ( # noqa: E402 F401
|
||||
Burg,
|
||||
Burgyl,
|
||||
Redor,
|
||||
Oryel,
|
||||
Peach,
|
||||
Pinkyl,
|
||||
Mint,
|
||||
Blugrn,
|
||||
Darkmint,
|
||||
Emrld,
|
||||
Aggrnyl,
|
||||
Bluyl,
|
||||
Teal,
|
||||
Tealgrn,
|
||||
Purp,
|
||||
Purpor,
|
||||
Sunset,
|
||||
Magenta,
|
||||
Sunsetdark,
|
||||
Agsunset,
|
||||
Brwnyl,
|
||||
Burg_r,
|
||||
Burgyl_r,
|
||||
Redor_r,
|
||||
Oryel_r,
|
||||
Peach_r,
|
||||
Pinkyl_r,
|
||||
Mint_r,
|
||||
Blugrn_r,
|
||||
Darkmint_r,
|
||||
Emrld_r,
|
||||
Aggrnyl_r,
|
||||
Bluyl_r,
|
||||
Teal_r,
|
||||
Tealgrn_r,
|
||||
Purp_r,
|
||||
Purpor_r,
|
||||
Sunset_r,
|
||||
Magenta_r,
|
||||
Sunsetdark_r,
|
||||
Agsunset_r,
|
||||
Brwnyl_r,
|
||||
)
|
||||
|
||||
__all__ = ["swatches"]
|
75
lib/python3.11/site-packages/_plotly_utils/data_utils.py
Normal file
75
lib/python3.11/site-packages/_plotly_utils/data_utils.py
Normal file
@ -0,0 +1,75 @@
|
||||
from io import BytesIO
|
||||
import base64
|
||||
from .png import Writer, from_array
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
|
||||
pil_imported = True
|
||||
except ImportError:
|
||||
pil_imported = False
|
||||
|
||||
|
||||
def image_array_to_data_uri(img, backend="pil", compression=4, ext="png"):
|
||||
"""Converts a numpy array of uint8 into a base64 png or jpg string.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
img: ndarray of uint8
|
||||
array image
|
||||
backend: str
|
||||
'auto', 'pil' or 'pypng'. If 'auto', Pillow is used if installed,
|
||||
otherwise pypng.
|
||||
compression: int, between 0 and 9
|
||||
compression level to be passed to the backend
|
||||
ext: str, 'png' or 'jpg'
|
||||
compression format used to generate b64 string
|
||||
"""
|
||||
# PIL and pypng error messages are quite obscure so we catch invalid compression values
|
||||
if compression < 0 or compression > 9:
|
||||
raise ValueError("compression level must be between 0 and 9.")
|
||||
alpha = False
|
||||
if img.ndim == 2:
|
||||
mode = "L"
|
||||
elif img.ndim == 3 and img.shape[-1] == 3:
|
||||
mode = "RGB"
|
||||
elif img.ndim == 3 and img.shape[-1] == 4:
|
||||
mode = "RGBA"
|
||||
alpha = True
|
||||
else:
|
||||
raise ValueError("Invalid image shape")
|
||||
if backend == "auto":
|
||||
backend = "pil" if pil_imported else "pypng"
|
||||
if ext != "png" and backend != "pil":
|
||||
raise ValueError("jpg binary strings are only available with PIL backend")
|
||||
|
||||
if backend == "pypng":
|
||||
ndim = img.ndim
|
||||
sh = img.shape
|
||||
if ndim == 3:
|
||||
img = img.reshape((sh[0], sh[1] * sh[2]))
|
||||
w = Writer(
|
||||
sh[1], sh[0], greyscale=(ndim == 2), alpha=alpha, compression=compression
|
||||
)
|
||||
img_png = from_array(img, mode=mode)
|
||||
prefix = "data:image/png;base64,"
|
||||
with BytesIO() as stream:
|
||||
w.write(stream, img_png.rows)
|
||||
base64_string = prefix + base64.b64encode(stream.getvalue()).decode("utf-8")
|
||||
else: # pil
|
||||
if not pil_imported:
|
||||
raise ImportError(
|
||||
"pillow needs to be installed to use `backend='pil'. Please"
|
||||
"install pillow or use `backend='pypng'."
|
||||
)
|
||||
pil_img = Image.fromarray(img)
|
||||
if ext == "jpg" or ext == "jpeg":
|
||||
prefix = "data:image/jpeg;base64,"
|
||||
ext = "jpeg"
|
||||
else:
|
||||
prefix = "data:image/png;base64,"
|
||||
ext = "png"
|
||||
with BytesIO() as stream:
|
||||
pil_img.save(stream, format=ext, compress_level=compression)
|
||||
base64_string = prefix + base64.b64encode(stream.getvalue()).decode("utf-8")
|
||||
return base64_string
|
97
lib/python3.11/site-packages/_plotly_utils/exceptions.py
Normal file
97
lib/python3.11/site-packages/_plotly_utils/exceptions.py
Normal file
@ -0,0 +1,97 @@
|
||||
class PlotlyError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PlotlyEmptyDataError(PlotlyError):
|
||||
pass
|
||||
|
||||
|
||||
class PlotlyGraphObjectError(PlotlyError):
|
||||
def __init__(self, message="", path=(), notes=()):
|
||||
"""
|
||||
General graph object error for validation failures.
|
||||
|
||||
:param (str|unicode) message: The error message.
|
||||
:param (iterable) path: A path pointing to the error.
|
||||
:param notes: Add additional notes, but keep default exception message.
|
||||
|
||||
"""
|
||||
self.message = message
|
||||
self.plain_message = message # for backwards compat
|
||||
self.path = list(path)
|
||||
self.notes = notes
|
||||
super(PlotlyGraphObjectError, self).__init__(message)
|
||||
|
||||
def __str__(self):
|
||||
"""This is called by Python to present the error message."""
|
||||
format_dict = {
|
||||
"message": self.message,
|
||||
"path": "[" + "][".join(repr(k) for k in self.path) + "]",
|
||||
"notes": "\n".join(self.notes),
|
||||
}
|
||||
return "{message}\n\nPath To Error: {path}\n\n{notes}".format(**format_dict)
|
||||
|
||||
|
||||
class PlotlyDictKeyError(PlotlyGraphObjectError):
|
||||
def __init__(self, obj, path, notes=()):
|
||||
"""See PlotlyGraphObjectError.__init__ for param docs."""
|
||||
format_dict = {"attribute": path[-1], "object_name": obj._name}
|
||||
message = "'{attribute}' is not allowed in '{object_name}'".format(
|
||||
**format_dict
|
||||
)
|
||||
notes = [obj.help(return_help=True)] + list(notes)
|
||||
super(PlotlyDictKeyError, self).__init__(
|
||||
message=message, path=path, notes=notes
|
||||
)
|
||||
|
||||
|
||||
class PlotlyDictValueError(PlotlyGraphObjectError):
|
||||
def __init__(self, obj, path, notes=()):
|
||||
"""See PlotlyGraphObjectError.__init__ for param docs."""
|
||||
format_dict = {"attribute": path[-1], "object_name": obj._name}
|
||||
message = "'{attribute}' has invalid value inside '{object_name}'".format(
|
||||
**format_dict
|
||||
)
|
||||
notes = [obj.help(path[-1], return_help=True)] + list(notes)
|
||||
super(PlotlyDictValueError, self).__init__(
|
||||
message=message, notes=notes, path=path
|
||||
)
|
||||
|
||||
|
||||
class PlotlyListEntryError(PlotlyGraphObjectError):
|
||||
def __init__(self, obj, path, notes=()):
|
||||
"""See PlotlyGraphObjectError.__init__ for param docs."""
|
||||
format_dict = {"index": path[-1], "object_name": obj._name}
|
||||
message = "Invalid entry found in '{object_name}' at index, '{index}'".format(
|
||||
**format_dict
|
||||
)
|
||||
notes = [obj.help(return_help=True)] + list(notes)
|
||||
super(PlotlyListEntryError, self).__init__(
|
||||
message=message, path=path, notes=notes
|
||||
)
|
||||
|
||||
|
||||
class PlotlyDataTypeError(PlotlyGraphObjectError):
|
||||
def __init__(self, obj, path, notes=()):
|
||||
"""See PlotlyGraphObjectError.__init__ for param docs."""
|
||||
format_dict = {"index": path[-1], "object_name": obj._name}
|
||||
message = "Invalid entry found in '{object_name}' at index, '{index}'".format(
|
||||
**format_dict
|
||||
)
|
||||
note = "It's invalid because it doesn't contain a valid 'type' value."
|
||||
notes = [note] + list(notes)
|
||||
super(PlotlyDataTypeError, self).__init__(
|
||||
message=message, path=path, notes=notes
|
||||
)
|
||||
|
||||
|
||||
class PlotlyKeyError(KeyError):
|
||||
"""
|
||||
KeyErrors are not printed as beautifully as other errors (this is so that
|
||||
{}[''] prints "KeyError: ''" and not "KeyError:"). So here we use
|
||||
LookupError's __str__ to make a PlotlyKeyError object which will print nicer
|
||||
error messages for KeyErrors.
|
||||
"""
|
||||
|
||||
def __str__(self):
|
||||
return LookupError.__str__(self)
|
37
lib/python3.11/site-packages/_plotly_utils/files.py
Normal file
37
lib/python3.11/site-packages/_plotly_utils/files.py
Normal file
@ -0,0 +1,37 @@
|
||||
import os
|
||||
|
||||
PLOTLY_DIR = os.environ.get(
|
||||
"PLOTLY_DIR", os.path.join(os.path.expanduser("~"), ".plotly")
|
||||
)
|
||||
TEST_FILE = os.path.join(PLOTLY_DIR, ".permission_test")
|
||||
|
||||
|
||||
def _permissions():
|
||||
try:
|
||||
if not os.path.exists(PLOTLY_DIR):
|
||||
try:
|
||||
os.mkdir(PLOTLY_DIR)
|
||||
except Exception:
|
||||
# in case of race
|
||||
if not os.path.isdir(PLOTLY_DIR):
|
||||
raise
|
||||
with open(TEST_FILE, "w") as f:
|
||||
f.write("testing\n")
|
||||
try:
|
||||
os.remove(TEST_FILE)
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
except Exception: # Do not trap KeyboardInterrupt.
|
||||
return False
|
||||
|
||||
|
||||
_file_permissions = None
|
||||
|
||||
|
||||
def ensure_writable_plotly_dir():
|
||||
# Cache permissions status
|
||||
global _file_permissions
|
||||
if _file_permissions is None:
|
||||
_file_permissions = _permissions()
|
||||
return _file_permissions
|
50
lib/python3.11/site-packages/_plotly_utils/importers.py
Normal file
50
lib/python3.11/site-packages/_plotly_utils/importers.py
Normal file
@ -0,0 +1,50 @@
|
||||
import importlib
|
||||
|
||||
|
||||
def relative_import(parent_name, rel_modules=(), rel_classes=()):
|
||||
"""
|
||||
Helper function to import submodules lazily in Python 3.7+
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rel_modules: list of str
|
||||
list of submodules to import, of the form .submodule
|
||||
rel_classes: list of str
|
||||
list of submodule classes/variables to import, of the form ._submodule.Foo
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
Tuple that should be assigned to __all__, __getattr__ in the caller
|
||||
"""
|
||||
module_names = {rel_module.split(".")[-1]: rel_module for rel_module in rel_modules}
|
||||
class_names = {rel_path.split(".")[-1]: rel_path for rel_path in rel_classes}
|
||||
|
||||
def __getattr__(import_name):
|
||||
# In Python 3.7+, lazy import submodules
|
||||
|
||||
# Check for submodule
|
||||
if import_name in module_names:
|
||||
rel_import = module_names[import_name]
|
||||
return importlib.import_module(rel_import, parent_name)
|
||||
|
||||
# Check for submodule class
|
||||
if import_name in class_names:
|
||||
rel_path_parts = class_names[import_name].split(".")
|
||||
rel_module = ".".join(rel_path_parts[:-1])
|
||||
class_name = import_name
|
||||
class_module = importlib.import_module(rel_module, parent_name)
|
||||
return getattr(class_module, class_name)
|
||||
|
||||
raise AttributeError(
|
||||
"module {__name__!r} has no attribute {name!r}".format(
|
||||
name=import_name, __name__=parent_name
|
||||
)
|
||||
)
|
||||
|
||||
__all__ = list(module_names) + list(class_names)
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
return __all__, __getattr__, __dir__
|
@ -0,0 +1,36 @@
|
||||
"""
|
||||
Stand-alone module to provide information about whether optional deps exist.
|
||||
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
import logging
|
||||
import sys
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
_not_importable = set()
|
||||
|
||||
|
||||
def get_module(name, should_load=True):
|
||||
"""
|
||||
Return module or None. Absolute import is required.
|
||||
|
||||
:param (str) name: Dot-separated module path. E.g., 'scipy.stats'.
|
||||
:raise: (ImportError) Only when exc_msg is defined.
|
||||
:return: (module|None) If import succeeds, the module will be returned.
|
||||
|
||||
"""
|
||||
if not should_load:
|
||||
return sys.modules.get(name, None)
|
||||
|
||||
if name not in _not_importable:
|
||||
try:
|
||||
return import_module(name)
|
||||
except ImportError:
|
||||
_not_importable.add(name)
|
||||
except Exception:
|
||||
_not_importable.add(name)
|
||||
msg = f"Error importing optional module {name}"
|
||||
logger.exception(msg)
|
||||
|
||||
return None
|
2350
lib/python3.11/site-packages/_plotly_utils/png.py
Normal file
2350
lib/python3.11/site-packages/_plotly_utils/png.py
Normal file
File diff suppressed because it is too large
Load Diff
557
lib/python3.11/site-packages/_plotly_utils/utils.py
Normal file
557
lib/python3.11/site-packages/_plotly_utils/utils.py
Normal file
@ -0,0 +1,557 @@
|
||||
import base64
|
||||
import decimal
|
||||
import json as _json
|
||||
import sys
|
||||
import re
|
||||
from functools import reduce
|
||||
|
||||
from _plotly_utils.optional_imports import get_module
|
||||
from _plotly_utils.basevalidators import (
|
||||
ImageUriValidator,
|
||||
copy_to_readonly_numpy_array,
|
||||
is_homogeneous_array,
|
||||
)
|
||||
|
||||
|
||||
int8min = -128
|
||||
int8max = 127
|
||||
int16min = -32768
|
||||
int16max = 32767
|
||||
int32min = -2147483648
|
||||
int32max = 2147483647
|
||||
|
||||
uint8max = 255
|
||||
uint16max = 65535
|
||||
uint32max = 4294967295
|
||||
|
||||
plotlyjsShortTypes = {
|
||||
"int8": "i1",
|
||||
"uint8": "u1",
|
||||
"int16": "i2",
|
||||
"uint16": "u2",
|
||||
"int32": "i4",
|
||||
"uint32": "u4",
|
||||
"float32": "f4",
|
||||
"float64": "f8",
|
||||
}
|
||||
|
||||
|
||||
def to_typed_array_spec(v):
|
||||
"""
|
||||
Convert numpy array to plotly.js typed array spec
|
||||
If not possible return the original value
|
||||
"""
|
||||
v = copy_to_readonly_numpy_array(v)
|
||||
|
||||
# Skip b64 encoding if numpy is not installed,
|
||||
# or if v is not a numpy array, or if v is empty
|
||||
np = get_module("numpy", should_load=False)
|
||||
if not np or not isinstance(v, np.ndarray) or v.size == 0:
|
||||
return v
|
||||
|
||||
dtype = str(v.dtype)
|
||||
|
||||
# convert default Big Ints until we could support them in plotly.js
|
||||
if dtype == "int64":
|
||||
max = v.max()
|
||||
min = v.min()
|
||||
if max <= int8max and min >= int8min:
|
||||
v = v.astype("int8")
|
||||
elif max <= int16max and min >= int16min:
|
||||
v = v.astype("int16")
|
||||
elif max <= int32max and min >= int32min:
|
||||
v = v.astype("int32")
|
||||
else:
|
||||
return v
|
||||
|
||||
elif dtype == "uint64":
|
||||
max = v.max()
|
||||
min = v.min()
|
||||
if max <= uint8max and min >= 0:
|
||||
v = v.astype("uint8")
|
||||
elif max <= uint16max and min >= 0:
|
||||
v = v.astype("uint16")
|
||||
elif max <= uint32max and min >= 0:
|
||||
v = v.astype("uint32")
|
||||
else:
|
||||
return v
|
||||
|
||||
dtype = str(v.dtype)
|
||||
|
||||
if dtype in plotlyjsShortTypes:
|
||||
arrObj = {
|
||||
"dtype": plotlyjsShortTypes[dtype],
|
||||
"bdata": base64.b64encode(v).decode("ascii"),
|
||||
}
|
||||
|
||||
if v.ndim > 1:
|
||||
arrObj["shape"] = str(v.shape)[1:-1]
|
||||
|
||||
return arrObj
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def is_skipped_key(key):
|
||||
"""
|
||||
Return whether the key is skipped for conversion to the typed array spec
|
||||
"""
|
||||
skipped_keys = ["geojson", "layer", "layers", "range"]
|
||||
return any(skipped_key == key for skipped_key in skipped_keys)
|
||||
|
||||
|
||||
def convert_to_base64(obj):
|
||||
if isinstance(obj, dict):
|
||||
for key, value in obj.items():
|
||||
if is_skipped_key(key):
|
||||
continue
|
||||
elif is_homogeneous_array(value):
|
||||
obj[key] = to_typed_array_spec(value)
|
||||
else:
|
||||
convert_to_base64(value)
|
||||
elif isinstance(obj, list) or isinstance(obj, tuple):
|
||||
for value in obj:
|
||||
convert_to_base64(value)
|
||||
|
||||
|
||||
def cumsum(x):
|
||||
"""
|
||||
Custom cumsum to avoid a numpy import.
|
||||
"""
|
||||
|
||||
def _reducer(a, x):
|
||||
if len(a) == 0:
|
||||
return [x]
|
||||
return a + [a[-1] + x]
|
||||
|
||||
ret = reduce(_reducer, x, [])
|
||||
return ret
|
||||
|
||||
|
||||
class PlotlyJSONEncoder(_json.JSONEncoder):
|
||||
"""
|
||||
Meant to be passed as the `cls` kwarg to json.dumps(obj, cls=..)
|
||||
|
||||
See PlotlyJSONEncoder.default for more implementation information.
|
||||
|
||||
Additionally, this encoder overrides nan functionality so that 'Inf',
|
||||
'NaN' and '-Inf' encode to 'null'. Which is stricter JSON than the Python
|
||||
version.
|
||||
|
||||
"""
|
||||
|
||||
def coerce_to_strict(self, const):
|
||||
"""
|
||||
This is used to ultimately *encode* into strict JSON, see `encode`
|
||||
|
||||
"""
|
||||
# before python 2.7, 'true', 'false', 'null', were include here.
|
||||
if const in ("Infinity", "-Infinity", "NaN"):
|
||||
return None
|
||||
else:
|
||||
return const
|
||||
|
||||
def encode(self, o):
|
||||
"""
|
||||
Load and then dump the result using parse_constant kwarg
|
||||
|
||||
Note that setting invalid separators will cause a failure at this step.
|
||||
|
||||
"""
|
||||
# this will raise errors in a normal-expected way
|
||||
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
|
||||
# Brute force guessing whether NaN or Infinity values are in the string
|
||||
# We catch false positive cases (e.g. strings such as titles, labels etc.)
|
||||
# but this is ok since the intention is to skip the decoding / reencoding
|
||||
# step when it's completely safe
|
||||
|
||||
if not ("NaN" in encoded_o or "Infinity" in encoded_o):
|
||||
return encoded_o
|
||||
|
||||
# now:
|
||||
# 1. `loads` to switch Infinity, -Infinity, NaN to None
|
||||
# 2. `dumps` again so you get 'null' instead of extended JSON
|
||||
try:
|
||||
new_o = _json.loads(encoded_o, parse_constant=self.coerce_to_strict)
|
||||
except ValueError:
|
||||
# invalid separators will fail here. raise a helpful exception
|
||||
raise ValueError(
|
||||
"Encoding into strict JSON failed. Did you set the separators "
|
||||
"valid JSON separators?"
|
||||
)
|
||||
else:
|
||||
return _json.dumps(
|
||||
new_o,
|
||||
sort_keys=self.sort_keys,
|
||||
indent=self.indent,
|
||||
separators=(self.item_separator, self.key_separator),
|
||||
)
|
||||
|
||||
def default(self, obj):
|
||||
"""
|
||||
Accept an object (of unknown type) and try to encode with priority:
|
||||
1. builtin: user-defined objects
|
||||
2. sage: sage math cloud
|
||||
3. pandas: dataframes/series
|
||||
4. numpy: ndarrays
|
||||
5. datetime: time/datetime objects
|
||||
|
||||
Each method throws a NotEncoded exception if it fails.
|
||||
|
||||
The default method will only get hit if the object is not a type that
|
||||
is naturally encoded by json:
|
||||
|
||||
Normal objects:
|
||||
dict object
|
||||
list, tuple array
|
||||
str, unicode string
|
||||
int, long, float number
|
||||
True true
|
||||
False false
|
||||
None null
|
||||
|
||||
Extended objects:
|
||||
float('nan') 'NaN'
|
||||
float('infinity') 'Infinity'
|
||||
float('-infinity') '-Infinity'
|
||||
|
||||
Therefore, we only anticipate either unknown iterables or values here.
|
||||
|
||||
"""
|
||||
# TODO: The ordering if these methods is *very* important. Is this OK?
|
||||
encoding_methods = (
|
||||
self.encode_as_plotly,
|
||||
self.encode_as_sage,
|
||||
self.encode_as_numpy,
|
||||
self.encode_as_pandas,
|
||||
self.encode_as_datetime,
|
||||
self.encode_as_date,
|
||||
self.encode_as_list, # because some values have `tolist` do last.
|
||||
self.encode_as_decimal,
|
||||
self.encode_as_pil,
|
||||
)
|
||||
for encoding_method in encoding_methods:
|
||||
try:
|
||||
return encoding_method(obj)
|
||||
except NotEncodable:
|
||||
pass
|
||||
return _json.JSONEncoder.default(self, obj)
|
||||
|
||||
@staticmethod
|
||||
def encode_as_plotly(obj):
|
||||
"""Attempt to use a builtin `to_plotly_json` method."""
|
||||
try:
|
||||
return obj.to_plotly_json()
|
||||
except AttributeError:
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_list(obj):
|
||||
"""Attempt to use `tolist` method to convert to normal Python list."""
|
||||
if hasattr(obj, "tolist"):
|
||||
return obj.tolist()
|
||||
else:
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_sage(obj):
|
||||
"""Attempt to convert sage.all.RR to floats and sage.all.ZZ to ints"""
|
||||
sage_all = get_module("sage.all")
|
||||
if not sage_all:
|
||||
raise NotEncodable
|
||||
|
||||
if obj in sage_all.RR:
|
||||
return float(obj)
|
||||
elif obj in sage_all.ZZ:
|
||||
return int(obj)
|
||||
else:
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_pandas(obj):
|
||||
"""Attempt to convert pandas.NaT / pandas.NA"""
|
||||
pandas = get_module("pandas", should_load=False)
|
||||
if not pandas:
|
||||
raise NotEncodable
|
||||
|
||||
if obj is pandas.NaT:
|
||||
return None
|
||||
|
||||
# pandas.NA was introduced in pandas 1.0
|
||||
if hasattr(pandas, "NA") and obj is pandas.NA:
|
||||
return None
|
||||
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_numpy(obj):
|
||||
"""Attempt to convert numpy.ma.core.masked"""
|
||||
numpy = get_module("numpy", should_load=False)
|
||||
if not numpy:
|
||||
raise NotEncodable
|
||||
|
||||
if obj is numpy.ma.core.masked:
|
||||
return float("nan")
|
||||
elif isinstance(obj, numpy.ndarray) and obj.dtype.kind == "M":
|
||||
try:
|
||||
return numpy.datetime_as_string(obj).tolist()
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_datetime(obj):
|
||||
"""Convert datetime objects to iso-format strings"""
|
||||
try:
|
||||
return obj.isoformat()
|
||||
except AttributeError:
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_date(obj):
|
||||
"""Attempt to convert to utc-iso time string using date methods."""
|
||||
try:
|
||||
time_string = obj.isoformat()
|
||||
except AttributeError:
|
||||
raise NotEncodable
|
||||
else:
|
||||
return iso_to_plotly_time_string(time_string)
|
||||
|
||||
@staticmethod
|
||||
def encode_as_decimal(obj):
|
||||
"""Attempt to encode decimal by converting it to float"""
|
||||
if isinstance(obj, decimal.Decimal):
|
||||
return float(obj)
|
||||
else:
|
||||
raise NotEncodable
|
||||
|
||||
@staticmethod
|
||||
def encode_as_pil(obj):
|
||||
"""Attempt to convert PIL.Image.Image to base64 data uri"""
|
||||
image = get_module("PIL.Image")
|
||||
if image is not None and isinstance(obj, image.Image):
|
||||
return ImageUriValidator.pil_image_to_uri(obj)
|
||||
else:
|
||||
raise NotEncodable
|
||||
|
||||
|
||||
class NotEncodable(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def iso_to_plotly_time_string(iso_string):
|
||||
"""Remove timezone info and replace 'T' delimeter with ' ' (ws)."""
|
||||
# make sure we don't send timezone info to plotly
|
||||
if (iso_string.split("-")[:3] == "00:00") or (iso_string.split("+")[0] == "00:00"):
|
||||
raise Exception(
|
||||
"Plotly won't accept timestrings with timezone info.\n"
|
||||
"All timestrings are assumed to be in UTC."
|
||||
)
|
||||
|
||||
iso_string = iso_string.replace("-00:00", "").replace("+00:00", "")
|
||||
|
||||
if iso_string.endswith("T00:00:00"):
|
||||
return iso_string.replace("T00:00:00", "")
|
||||
else:
|
||||
return iso_string.replace("T", " ")
|
||||
|
||||
|
||||
def template_doc(**names):
|
||||
def _decorator(func):
|
||||
if not sys.version_info[:2] == (3, 2):
|
||||
if func.__doc__ is not None:
|
||||
func.__doc__ = func.__doc__.format(**names)
|
||||
return func
|
||||
|
||||
return _decorator
|
||||
|
||||
|
||||
def _natural_sort_strings(vals, reverse=False):
|
||||
def key(v):
|
||||
v_parts = re.split(r"(\d+)", v)
|
||||
for i in range(len(v_parts)):
|
||||
try:
|
||||
v_parts[i] = int(v_parts[i])
|
||||
except ValueError:
|
||||
# not an int
|
||||
pass
|
||||
return tuple(v_parts)
|
||||
|
||||
return sorted(vals, key=key, reverse=reverse)
|
||||
|
||||
|
||||
def _get_int_type():
|
||||
np = get_module("numpy", should_load=False)
|
||||
if np:
|
||||
int_type = (int, np.integer)
|
||||
else:
|
||||
int_type = (int,)
|
||||
return int_type
|
||||
|
||||
|
||||
def split_multichar(ss, chars):
|
||||
"""
|
||||
Split all the strings in ss at any of the characters in chars.
|
||||
Example:
|
||||
|
||||
>>> ss = ["a.string[0].with_separators"]
|
||||
>>> chars = list(".[]_")
|
||||
>>> split_multichar(ss, chars)
|
||||
['a', 'string', '0', '', 'with', 'separators']
|
||||
|
||||
:param (list) ss: A list of strings.
|
||||
:param (list) chars: Is a list of chars (note: not a string).
|
||||
"""
|
||||
if len(chars) == 0:
|
||||
return ss
|
||||
c = chars.pop()
|
||||
ss = reduce(lambda x, y: x + y, map(lambda x: x.split(c), ss))
|
||||
return split_multichar(ss, chars)
|
||||
|
||||
|
||||
def split_string_positions(ss):
|
||||
"""
|
||||
Given a list of strings split using split_multichar, return a list of
|
||||
integers representing the indices of the first character of every string in
|
||||
the original string.
|
||||
Example:
|
||||
|
||||
>>> ss = ["a.string[0].with_separators"]
|
||||
>>> chars = list(".[]_")
|
||||
>>> ss_split = split_multichar(ss, chars)
|
||||
>>> ss_split
|
||||
['a', 'string', '0', '', 'with', 'separators']
|
||||
>>> split_string_positions(ss_split)
|
||||
[0, 2, 9, 11, 12, 17]
|
||||
|
||||
:param (list) ss: A list of strings.
|
||||
"""
|
||||
return list(
|
||||
map(
|
||||
lambda t: t[0] + t[1],
|
||||
zip(range(len(ss)), cumsum([0] + list(map(len, ss[:-1])))),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def display_string_positions(p, i=None, offset=0, length=1, char="^", trim=True):
|
||||
"""
|
||||
Return a string that is whitespace except at p[i] which is replaced with char.
|
||||
If i is None then all the indices of the string in p are replaced with char.
|
||||
|
||||
Example:
|
||||
|
||||
>>> ss = ["a.string[0].with_separators"]
|
||||
>>> chars = list(".[]_")
|
||||
>>> ss_split = split_multichar(ss, chars)
|
||||
>>> ss_split
|
||||
['a', 'string', '0', '', 'with', 'separators']
|
||||
>>> ss_pos = split_string_positions(ss_split)
|
||||
>>> ss[0]
|
||||
'a.string[0].with_separators'
|
||||
>>> display_string_positions(ss_pos,4)
|
||||
' ^'
|
||||
>>> display_string_positions(ss_pos,4,offset=1,length=3,char="~",trim=False)
|
||||
' ~~~ '
|
||||
>>> display_string_positions(ss_pos)
|
||||
'^ ^ ^ ^^ ^'
|
||||
:param (list) p: A list of integers.
|
||||
:param (integer|None) i: Optional index of p to display.
|
||||
:param (integer) offset: Allows adding a number of spaces to the replacement.
|
||||
:param (integer) length: Allows adding a replacement that is the char
|
||||
repeated length times.
|
||||
:param (str) char: allows customizing the replacement character.
|
||||
:param (boolean) trim: trims the remaining whitespace if True.
|
||||
"""
|
||||
s = [" " for _ in range(max(p) + 1 + offset + length)]
|
||||
maxaddr = 0
|
||||
if i is None:
|
||||
for p_ in p:
|
||||
for temp in range(length):
|
||||
maxaddr = p_ + offset + temp
|
||||
s[maxaddr] = char
|
||||
else:
|
||||
for temp in range(length):
|
||||
maxaddr = p[i] + offset + temp
|
||||
s[maxaddr] = char
|
||||
ret = "".join(s)
|
||||
if trim:
|
||||
ret = ret[: maxaddr + 1]
|
||||
return ret
|
||||
|
||||
|
||||
def chomp_empty_strings(strings, c, reverse=False):
|
||||
"""
|
||||
Given a list of strings, some of which are the empty string "", replace the
|
||||
empty strings with c and combine them with the closest non-empty string on
|
||||
the left or "" if it is the first string.
|
||||
Examples:
|
||||
for c="_"
|
||||
['hey', '', 'why', '', '', 'whoa', '', ''] -> ['hey_', 'why__', 'whoa__']
|
||||
['', 'hi', '', "I'm", 'bob', '', ''] -> ['_', 'hi_', "I'm", 'bob__']
|
||||
['hi', "i'm", 'a', 'good', 'string'] -> ['hi', "i'm", 'a', 'good', 'string']
|
||||
Some special cases are:
|
||||
[] -> []
|
||||
[''] -> ['']
|
||||
['', ''] -> ['_']
|
||||
['', '', '', ''] -> ['___']
|
||||
If reverse is true, empty strings are combined with closest non-empty string
|
||||
on the right or "" if it is the last string.
|
||||
"""
|
||||
|
||||
def _rev(vals):
|
||||
return [s[::-1] for s in vals][::-1]
|
||||
|
||||
if reverse:
|
||||
return _rev(chomp_empty_strings(_rev(strings), c))
|
||||
if not len(strings):
|
||||
return strings
|
||||
if sum(map(len, strings)) == 0:
|
||||
return [c * (len(strings) - 1)]
|
||||
|
||||
class _Chomper:
|
||||
def __init__(self, c):
|
||||
self.c = c
|
||||
|
||||
def __call__(self, x, y):
|
||||
# x is list up to now
|
||||
# y is next item in list
|
||||
# x should be [""] initially, and then empty strings filtered out at the
|
||||
# end
|
||||
if len(y) == 0:
|
||||
return x[:-1] + [x[-1] + self.c]
|
||||
else:
|
||||
return x + [y]
|
||||
|
||||
return list(filter(len, reduce(_Chomper(c), strings, [""])))
|
||||
|
||||
|
||||
# taken from
|
||||
# https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Python
|
||||
def levenshtein(s1, s2):
|
||||
if len(s1) < len(s2):
|
||||
return levenshtein(s2, s1) # len(s1) >= len(s2)
|
||||
if len(s2) == 0:
|
||||
return len(s1)
|
||||
previous_row = range(len(s2) + 1)
|
||||
for i, c1 in enumerate(s1):
|
||||
current_row = [i + 1]
|
||||
for j, c2 in enumerate(s2):
|
||||
# j+1 instead of j since previous_row and current_row are one character longer
|
||||
# than s2
|
||||
insertions = previous_row[j + 1] + 1
|
||||
deletions = current_row[j] + 1
|
||||
substitutions = previous_row[j] + (c1 != c2)
|
||||
current_row.append(min(insertions, deletions, substitutions))
|
||||
previous_row = current_row
|
||||
return previous_row[-1]
|
||||
|
||||
|
||||
def find_closest_string(string, strings):
|
||||
def _key(s):
|
||||
# sort by levenshtein distance and lexographically to maintain a stable
|
||||
# sort for different keys with the same levenshtein distance
|
||||
return (levenshtein(s, string), s)
|
||||
|
||||
return sorted(strings, key=_key)[0]
|
Reference in New Issue
Block a user