lessPython 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lessPy/ANOVA.py +680 -0
- lessPy/Chart.py +1055 -0
- lessPy/Correlation.py +236 -0
- lessPy/Flows.py +116 -0
- lessPy/Logit.py +615 -0
- lessPy/Prop_test.py +267 -0
- lessPy/Regression.py +1491 -0
- lessPy/VariableLabels.py +119 -0
- lessPy/X.py +426 -0
- lessPy/XY.py +2007 -0
- lessPy/__init__.py +60 -0
- lessPy/anova_rmd.py +227 -0
- lessPy/bc_plotly.py +575 -0
- lessPy/bubble_plotly.py +470 -0
- lessPy/corCFA.py +316 -0
- lessPy/corEFA.py +220 -0
- lessPy/corPrint.py +45 -0
- lessPy/corProp.py +73 -0
- lessPy/corRead.py +48 -0
- lessPy/corReflect.py +72 -0
- lessPy/corReorder.py +161 -0
- lessPy/corScree.py +87 -0
- lessPy/data/Anova_1way.csv +25 -0
- lessPy/data/Anova_2way.csv +49 -0
- lessPy/data/Anova_rb.csv +8 -0
- lessPy/data/Anova_rbf.csv +49 -0
- lessPy/data/Anova_sp.csv +57 -0
- lessPy/data/BodyMeas.csv +341 -0
- lessPy/data/Cars93.csv +94 -0
- lessPy/data/Employee.csv +38 -0
- lessPy/data/Employee_lbl.csv +9 -0
- lessPy/data/FreqTable99.csv +5 -0
- lessPy/data/Jackets.csv +1026 -0
- lessPy/data/Learn.csv +35 -0
- lessPy/data/Mach4.csv +352 -0
- lessPy/data/Mach4_lbl.csv +21 -0
- lessPy/data/Reading.csv +101 -0
- lessPy/data/StockPrice.csv +1489 -0
- lessPy/data/WeightLoss.csv +11 -0
- lessPy/datasets.py +46 -0
- lessPy/date_infer.py +112 -0
- lessPy/details.py +314 -0
- lessPy/dn_plotly.py +495 -0
- lessPy/dot_plotly.py +385 -0
- lessPy/freq_poly_plotly.py +324 -0
- lessPy/getColors.py +399 -0
- lessPy/hier_plotly.py +352 -0
- lessPy/hs_plotly.py +395 -0
- lessPy/logit_rmd.py +410 -0
- lessPy/order_by.py +94 -0
- lessPy/pie_plotly.py +292 -0
- lessPy/pivot.py +158 -0
- lessPy/plotly_utils.py +787 -0
- lessPy/plt_add.py +129 -0
- lessPy/plt_contour.py +192 -0
- lessPy/plt_contour_facet.py +194 -0
- lessPy/plt_forecast.py +677 -0
- lessPy/plt_mat_plotly.py +201 -0
- lessPy/plt_plotly.py +216 -0
- lessPy/plt_smooth.py +170 -0
- lessPy/plt_time.py +143 -0
- lessPy/prob_norm.py +111 -0
- lessPy/prob_tcut.py +131 -0
- lessPy/prob_znorm.py +110 -0
- lessPy/radar_plotly.py +201 -0
- lessPy/reg_rmd.py +754 -0
- lessPy/rename.py +33 -0
- lessPy/reshape.py +95 -0
- lessPy/showColors.py +130 -0
- lessPy/simCImean.py +165 -0
- lessPy/simCLT.py +265 -0
- lessPy/simFlips.py +104 -0
- lessPy/simMeans.py +146 -0
- lessPy/stats_out.py +189 -0
- lessPy/ttest.py +641 -0
- lessPy/utils.py +235 -0
- lessPy/vbs_plotly.py +545 -0
- lesspython-0.1.0.dist-info/METADATA +93 -0
- lesspython-0.1.0.dist-info/RECORD +82 -0
- lesspython-0.1.0.dist-info/WHEEL +5 -0
- lesspython-0.1.0.dist-info/licenses/LICENSE +338 -0
- lesspython-0.1.0.dist-info/top_level.txt +1 -0
lessPy/getColors.py
ADDED
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
# getColors.py — analog of getColors.R.
|
|
2
|
+
#
|
|
3
|
+
# getColors(): generate a color palette and return it as a list of
|
|
4
|
+
# hex strings, printing a small table of the colors unless quiet.
|
|
5
|
+
# The HCL families (hues/qualitative, sequential, divergent) are
|
|
6
|
+
# reproduced exactly from R's grDevices HCL and colorspace
|
|
7
|
+
# trajectories; the manual families interpolate in RGB; Okabe-Ito,
|
|
8
|
+
# Tableau and "distinct" are fixed lists. The viridis family maps
|
|
9
|
+
# to plotly's built-in colorscales (a documented approximation),
|
|
10
|
+
# and R's wesanderson palettes are not ported (external package).
|
|
11
|
+
|
|
12
|
+
import math
|
|
13
|
+
|
|
14
|
+
# --- fixed palettes -------------------------------------------------
|
|
15
|
+
|
|
16
|
+
# Okabe-Ito, in R's order minus the leading black, black appended
|
|
17
|
+
_OKABE_ITO = [
|
|
18
|
+
"#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2",
|
|
19
|
+
"#D55E00", "#CC79A7", "#999999", "#000000",
|
|
20
|
+
]
|
|
21
|
+
_TABLEAU = [
|
|
22
|
+
"#4E79A7", "#F28E2B", "#E15759", "#76B7B2", "#59A14F",
|
|
23
|
+
"#EDC949", "#AF7AA1", "#FF9DA7", "#9C755F", "#BAB0AC",
|
|
24
|
+
]
|
|
25
|
+
# R's "distinct" names resolved to hex (col2rgb)
|
|
26
|
+
_DISTINCT = [
|
|
27
|
+
"#EEB422", "#737373", "#9ACD32", "#CD69C9", "#87CEEB",
|
|
28
|
+
"#A9A9A9", "#F08080", "#8B795E", "#00CDCD", "#CD6600",
|
|
29
|
+
"#CD2990", "#66CDAA", "#4876FF", "#8B7D7B", "#CDB5CD",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
# hue (degrees) of each pre-defined HCL color sequence
|
|
33
|
+
_SEQ_HUE = {
|
|
34
|
+
"reds": 0, "rusts": 30, "browns": 60, "olives": 90,
|
|
35
|
+
"greens": 120, "emeralds": 150, "turquoises": 180,
|
|
36
|
+
"aquas": 210, "blues": 240, "purples": 270, "violets": 300,
|
|
37
|
+
"magentas": 330, "grays": 0,
|
|
38
|
+
}
|
|
39
|
+
_SEQ_NAMES = list(_SEQ_HUE)
|
|
40
|
+
_VIRIDIS = {"viridis": "Viridis", "cividis": "Cividis",
|
|
41
|
+
"plasma": "Plasma", "spectral": "Spectral"}
|
|
42
|
+
|
|
43
|
+
# D65 white point (grDevices HCL / colorspace polarLUV)
|
|
44
|
+
_XN, _YN, _ZN = 95.047, 100.0, 108.883
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# --- HCL -> sRGB (grDevices polarLUV, D65) --------------------------
|
|
48
|
+
|
|
49
|
+
def _gtrans(u):
|
|
50
|
+
if u > 0.0031308:
|
|
51
|
+
return 1.055 * u ** (1.0 / 2.4) - 0.055
|
|
52
|
+
return 12.92 * u
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def hcl(h, c, l, fixup=True):
|
|
56
|
+
"""One HCL (polarLUV) color as a hex string, matching R's
|
|
57
|
+
grDevices::hcl. Returns None when out of gamut and fixup is
|
|
58
|
+
False. R analog: hcl()"""
|
|
59
|
+
if l <= 0:
|
|
60
|
+
x = y = z = 0.0
|
|
61
|
+
else:
|
|
62
|
+
hrad = math.radians(h)
|
|
63
|
+
U = c * math.cos(hrad)
|
|
64
|
+
V = c * math.sin(hrad)
|
|
65
|
+
un = 4 * _XN / (_XN + 15 * _YN + 3 * _ZN)
|
|
66
|
+
vn = 9 * _YN / (_XN + 15 * _YN + 3 * _ZN)
|
|
67
|
+
if l > 7.999592:
|
|
68
|
+
y = _YN * ((l + 16) / 116) ** 3
|
|
69
|
+
else:
|
|
70
|
+
y = _YN * l / 903.3
|
|
71
|
+
up = U / (13 * l) + un
|
|
72
|
+
vp = V / (13 * l) + vn
|
|
73
|
+
x = 9 * y * up / (4 * vp)
|
|
74
|
+
z = y * (12 - 3 * up - 20 * vp) / (4 * vp)
|
|
75
|
+
|
|
76
|
+
xr, yr, zr = x / 100, y / 100, z / 100
|
|
77
|
+
r = 3.240479 * xr - 1.537150 * yr - 0.498535 * zr
|
|
78
|
+
g = -0.969256 * xr + 1.875992 * yr + 0.041556 * zr
|
|
79
|
+
b = 0.055648 * xr - 0.204043 * yr + 1.057311 * zr
|
|
80
|
+
rgb = [_gtrans(max(0.0, v)) for v in (r, g, b)]
|
|
81
|
+
|
|
82
|
+
if not fixup and any(v < -1e-6 or v > 1 + 1e-6 for v in rgb):
|
|
83
|
+
return None
|
|
84
|
+
ints = [min(255, max(0, round(v * 255))) for v in rgb]
|
|
85
|
+
return "#{:02X}{:02X}{:02X}".format(*ints)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _seq(n):
|
|
89
|
+
if n == 1:
|
|
90
|
+
return [0.0]
|
|
91
|
+
return [1.0 - i / (n - 1) for i in range(n)]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _sequential_hcl(n, h, c, l, power, fixup):
|
|
95
|
+
c1, c2 = (c, c) if not isinstance(c, tuple) else c
|
|
96
|
+
l1, l2 = (l, l) if not isinstance(l, tuple) else l
|
|
97
|
+
p1, p2 = (power, power) if not isinstance(power, tuple) else power
|
|
98
|
+
out = []
|
|
99
|
+
for r in _seq(n):
|
|
100
|
+
L = l2 - (l2 - l1) * r ** p2
|
|
101
|
+
C = c2 - (c2 - c1) * r ** p1
|
|
102
|
+
out.append(hcl(h, C, L, fixup) + "FF")
|
|
103
|
+
return out
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _diverging_hcl(n, h1, h2, c, l, power, fixup):
|
|
107
|
+
l1, l2 = (l, l) if not isinstance(l, tuple) else l
|
|
108
|
+
p1, p2 = (power, power) if not isinstance(power, tuple) else power
|
|
109
|
+
rvals = [1.0] if n == 1 else \
|
|
110
|
+
[1.0 - 2.0 * i / (n - 1) for i in range(n)]
|
|
111
|
+
out = []
|
|
112
|
+
for r in rvals:
|
|
113
|
+
L = l2 - (l2 - l1) * abs(r) ** p2
|
|
114
|
+
C = c * abs(r) ** p1
|
|
115
|
+
H = h1 if r > 0 else h2
|
|
116
|
+
out.append(hcl(H, C, L, fixup) + "FF")
|
|
117
|
+
return out
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# --- RGB ramp (colorRampPalette default space="rgb") ----------------
|
|
121
|
+
|
|
122
|
+
def _to_rgb(col):
|
|
123
|
+
from .plotly_utils import to_hex, hex_to_rgb3
|
|
124
|
+
return hex_to_rgb3(to_hex(col))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _rgb_to_hcl(r, g, b):
|
|
128
|
+
"""sRGB (0-255) -> HCL (polarLUV, D65): (hue_deg, chroma, lum).
|
|
129
|
+
The inverse of hcl(); used to read a named color's hue and
|
|
130
|
+
chroma for the value-scaled bar fills."""
|
|
131
|
+
def inv(v):
|
|
132
|
+
v /= 255.0
|
|
133
|
+
return (((v + 0.055) / 1.055) ** 2.4 if v > 0.04045
|
|
134
|
+
else v / 12.92)
|
|
135
|
+
R, G, B = inv(r), inv(g), inv(b)
|
|
136
|
+
X = (0.412453 * R + 0.357580 * G + 0.180423 * B) * 100
|
|
137
|
+
Y = (0.212671 * R + 0.715160 * G + 0.072169 * B) * 100
|
|
138
|
+
Z = (0.019334 * R + 0.119193 * G + 0.950227 * B) * 100
|
|
139
|
+
if Y <= 0:
|
|
140
|
+
return 0.0, 0.0, 0.0
|
|
141
|
+
yr = Y / _YN
|
|
142
|
+
L = (116 * yr ** (1 / 3) - 16 if yr > 0.008856 else 903.3 * yr)
|
|
143
|
+
d = X + 15 * Y + 3 * Z
|
|
144
|
+
if d == 0:
|
|
145
|
+
return 0.0, 0.0, L
|
|
146
|
+
un = 4 * _XN / (_XN + 15 * _YN + 3 * _ZN)
|
|
147
|
+
vn = 9 * _YN / (_XN + 15 * _YN + 3 * _ZN)
|
|
148
|
+
U = 13 * L * (4 * X / d - un)
|
|
149
|
+
V = 13 * L * (9 * Y / d - vn)
|
|
150
|
+
return math.degrees(math.atan2(V, U)) % 360, math.hypot(U, V), L
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _color_hc(col):
|
|
154
|
+
h, c, _ = _rgb_to_hcl(*_to_rgb(col))
|
|
155
|
+
return h, c
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def bar_fill_colors(values, fill, fill_split, fill_scaled,
|
|
159
|
+
fill_chroma=75):
|
|
160
|
+
"""Per-bar fill colors for a numeric bar chart, keyed to the bar
|
|
161
|
+
values. fill_split gives a two-color split at that value (below
|
|
162
|
+
-> first color, above -> second). fill_scaled makes an HCL
|
|
163
|
+
gradient: chroma and darkness rise with distance from the split
|
|
164
|
+
(default 0), hue by side. A faithful approximation of R's
|
|
165
|
+
.scale.clr, not colorspace-exact. R analog: fill_split /
|
|
166
|
+
fill_scaled."""
|
|
167
|
+
import numpy as np
|
|
168
|
+
from .plotly_utils import to_hex
|
|
169
|
+
x = np.asarray(values, dtype=float)
|
|
170
|
+
fills = (None if fill is None
|
|
171
|
+
else [fill] if isinstance(fill, str) else list(fill))
|
|
172
|
+
split = 0.0 if fill_split is None else float(fill_split)
|
|
173
|
+
|
|
174
|
+
if not fill_scaled: # discrete two-color split
|
|
175
|
+
if fills is not None and len(fills) == 2:
|
|
176
|
+
c1, c2 = to_hex(fills[0]), to_hex(fills[1])
|
|
177
|
+
else: # default dark/light pair
|
|
178
|
+
c1, c2 = hcl(255, 55, 30), hcl(255, 55, 70)
|
|
179
|
+
return [c1 if v <= split else c2 for v in x]
|
|
180
|
+
|
|
181
|
+
dist = np.abs(x - split)
|
|
182
|
+
mx = float(dist.max()) or 1.0
|
|
183
|
+
normed = dist / mx
|
|
184
|
+
lum = 27 + (1 - normed) * 53 # near split light, far dark
|
|
185
|
+
|
|
186
|
+
if fills is None or len(fills) > 2:
|
|
187
|
+
h1 = h2 = 255.0
|
|
188
|
+
c1 = c2 = float(fill_chroma)
|
|
189
|
+
elif len(fills) == 1:
|
|
190
|
+
h1, c1 = _color_hc(fills[0])
|
|
191
|
+
h2, c2 = h1, c1
|
|
192
|
+
else:
|
|
193
|
+
h1, c1 = _color_hc(fills[0])
|
|
194
|
+
h2, c2 = _color_hc(fills[1])
|
|
195
|
+
g1, g2 = c1 < 5, c2 < 5 # near-gray fill colors
|
|
196
|
+
|
|
197
|
+
out = []
|
|
198
|
+
for v, nm, L in zip(x, normed, lum):
|
|
199
|
+
if g1 and g2: # pure grayscale ramp
|
|
200
|
+
hue, chroma = 0.0, 0.0
|
|
201
|
+
elif g1 or g2: # sequential: chromatic hue
|
|
202
|
+
hue = h2 if g1 else h1
|
|
203
|
+
chroma = (c2 if g1 else c1) * nm
|
|
204
|
+
else: # diverging by side
|
|
205
|
+
below = v <= split
|
|
206
|
+
hue = h1 if below else h2
|
|
207
|
+
chroma = (c1 if below else c2) * nm
|
|
208
|
+
out.append(hcl(hue, chroma, max(1.0, L)))
|
|
209
|
+
return out
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _ramp(colors, n):
|
|
213
|
+
pts = [_to_rgb(c) for c in colors]
|
|
214
|
+
if n == 1:
|
|
215
|
+
r, g, b = pts[0]
|
|
216
|
+
return ["#{:02X}{:02X}{:02X}".format(r, g, b)]
|
|
217
|
+
m = len(pts) - 1
|
|
218
|
+
out = []
|
|
219
|
+
for i in range(n):
|
|
220
|
+
t = i / (n - 1) * m
|
|
221
|
+
j = min(int(math.floor(t)), m - 1)
|
|
222
|
+
f = t - j
|
|
223
|
+
rgb = [round(pts[j][k] + f * (pts[j + 1][k] - pts[j][k]))
|
|
224
|
+
for k in range(3)]
|
|
225
|
+
out.append("#{:02X}{:02X}{:02X}".format(*rgb))
|
|
226
|
+
return out
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _viridis(name, n):
|
|
230
|
+
from plotly.colors import sample_colorscale
|
|
231
|
+
xs = [0.0] if n == 1 else [i / (n - 1) for i in range(n)]
|
|
232
|
+
cols = sample_colorscale(_VIRIDIS[name], xs, colortype="rgb")
|
|
233
|
+
out = []
|
|
234
|
+
for c in cols:
|
|
235
|
+
r, g, b = (round(float(v)) for v in
|
|
236
|
+
c[c.find("(") + 1:c.find(")")].split(","))
|
|
237
|
+
out.append("#{:02X}{:02X}{:02X}".format(r, g, b))
|
|
238
|
+
return out
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
# the fixed mixed hues for a qualitative palette (n <= 24)
|
|
242
|
+
_MIX = [240, 60, 120, 0, 275, 180, 30, 90, 210, 330, 150, 300]
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def getColors(pal=None, end_pal=None, n=None, h=0, h2=None, c=None,
|
|
246
|
+
l=None, in_order=None, fixup=True, power=None,
|
|
247
|
+
transparency=0, quiet=False):
|
|
248
|
+
"""Generate a color palette, returning a list of hex colors and
|
|
249
|
+
(unless quiet) printing a table of them.
|
|
250
|
+
|
|
251
|
+
pal: a palette name ("hues", a sequential name such as "blues",
|
|
252
|
+
"viridis"/"cividis"/"plasma"/"spectral", "Okabe-Ito", "Tableau",
|
|
253
|
+
"distinct") or one or more explicit colors. end_pal: an ending
|
|
254
|
+
color/name for a divergent (two sequential names) or manual
|
|
255
|
+
(two colors) gradient. h/h2, c, l, power: HCL parameters.
|
|
256
|
+
R analog: getColors()"""
|
|
257
|
+
c_miss, l_miss = c is None, l is None
|
|
258
|
+
n_miss = n is None
|
|
259
|
+
if n_miss:
|
|
260
|
+
n = 12
|
|
261
|
+
|
|
262
|
+
if in_order is None:
|
|
263
|
+
in_order = False
|
|
264
|
+
if isinstance(pal, str):
|
|
265
|
+
pal = [pal]
|
|
266
|
+
if isinstance(pal, list) and pal and pal[0] == "yellows":
|
|
267
|
+
pal[0] = "browns"
|
|
268
|
+
if isinstance(pal, str) and pal == "magma":
|
|
269
|
+
pal = ["plasma"]
|
|
270
|
+
|
|
271
|
+
if pal is None and end_pal is None and not isinstance(c, list) \
|
|
272
|
+
and not isinstance(l, list):
|
|
273
|
+
pal = ["hues"]
|
|
274
|
+
|
|
275
|
+
# classify the request
|
|
276
|
+
if pal is not None:
|
|
277
|
+
p0 = pal[0]
|
|
278
|
+
if p0 in _SEQ_NAMES:
|
|
279
|
+
kind = "divergent" if (end_pal is not None and
|
|
280
|
+
end_pal[0] in _SEQ_NAMES) \
|
|
281
|
+
else "sequential"
|
|
282
|
+
elif p0 == "hues":
|
|
283
|
+
kind = "qualitative"
|
|
284
|
+
elif p0 in _VIRIDIS:
|
|
285
|
+
kind = "viridis"
|
|
286
|
+
elif p0 == "Okabe-Ito":
|
|
287
|
+
kind = "oi"
|
|
288
|
+
elif p0 == "Tableau":
|
|
289
|
+
kind = "Tableau"
|
|
290
|
+
elif p0 == "distinct":
|
|
291
|
+
kind = "distinct"
|
|
292
|
+
else:
|
|
293
|
+
kind = "manual.q" if end_pal is None else "manual.s"
|
|
294
|
+
else:
|
|
295
|
+
kind = "sequential" if (isinstance(c, list) or
|
|
296
|
+
isinstance(l, list)) else "qualitative"
|
|
297
|
+
|
|
298
|
+
# pre-defined sequential/divergent hues
|
|
299
|
+
if pal is not None and pal[0] in _SEQ_NAMES:
|
|
300
|
+
h = _SEQ_HUE[pal[0]]
|
|
301
|
+
if pal[0] == "grays":
|
|
302
|
+
c, c_miss = 0, False
|
|
303
|
+
if end_pal is None:
|
|
304
|
+
pal = None
|
|
305
|
+
if end_pal is not None and end_pal[0] in _SEQ_NAMES:
|
|
306
|
+
h2 = _SEQ_HUE[end_pal[0]]
|
|
307
|
+
if end_pal[0] == "grays":
|
|
308
|
+
c, c_miss = 0, False
|
|
309
|
+
pal = None
|
|
310
|
+
|
|
311
|
+
ttl = ""
|
|
312
|
+
|
|
313
|
+
if kind == "qualitative":
|
|
314
|
+
if h2 is None:
|
|
315
|
+
h2 = h + (360 * (n - 1) / n)
|
|
316
|
+
if n <= 24:
|
|
317
|
+
if not in_order:
|
|
318
|
+
hues = _MIX + [x + 15 for x in _MIX]
|
|
319
|
+
else:
|
|
320
|
+
hues = ([h] if n == 1 else
|
|
321
|
+
[h + (h2 - h) * i / (n - 1) for i in range(n)])
|
|
322
|
+
else:
|
|
323
|
+
hues = [h + (h2 - h) * i / (n - 1) for i in range(n)]
|
|
324
|
+
hues = [(x - 360 if x >= 360 else x + 360 if x < 0 else x)
|
|
325
|
+
for x in hues]
|
|
326
|
+
cc = 65 if c_miss else c
|
|
327
|
+
ll = 60 if l_miss else l
|
|
328
|
+
pal = [hcl(hues[i], cc, ll, fixup) for i in range(n)]
|
|
329
|
+
|
|
330
|
+
elif kind == "sequential":
|
|
331
|
+
cc = (35, 75) if c_miss else (c if isinstance(c, (tuple, list))
|
|
332
|
+
else (c, c))
|
|
333
|
+
l_dk = max(14, 35 - 3 * n)
|
|
334
|
+
l_lt = min(92, 52 + 5 * n)
|
|
335
|
+
ll = (l_lt, l_dk) if l_miss else (l if isinstance(l, (tuple,
|
|
336
|
+
list)) else (l, l))
|
|
337
|
+
pw = 1 if power is None else power
|
|
338
|
+
pal = _sequential_hcl(n, h, tuple(cc), tuple(ll), pw, fixup)
|
|
339
|
+
|
|
340
|
+
elif kind == "divergent":
|
|
341
|
+
cc = 50 if c_miss else (c[0] if isinstance(c, (tuple, list))
|
|
342
|
+
else c)
|
|
343
|
+
ll = (30, 80) if l_miss else (tuple(l) if isinstance(l, (tuple,
|
|
344
|
+
list)) else (l, l))
|
|
345
|
+
pw = 0.75 if power is None else power
|
|
346
|
+
pal = _diverging_hcl(n, h, h2, cc, ll, pw, fixup)
|
|
347
|
+
|
|
348
|
+
elif kind == "viridis":
|
|
349
|
+
ttl = "Viridis Style Palette: " + pal[0]
|
|
350
|
+
pal = _viridis(pal[0], n)
|
|
351
|
+
|
|
352
|
+
elif kind == "oi":
|
|
353
|
+
if n_miss:
|
|
354
|
+
n = 9
|
|
355
|
+
if n > 9:
|
|
356
|
+
raise ValueError("only 9 Okabe-Ito colors are available")
|
|
357
|
+
pal = _OKABE_ITO[:n]
|
|
358
|
+
|
|
359
|
+
elif kind == "Tableau":
|
|
360
|
+
if n_miss:
|
|
361
|
+
n = 10
|
|
362
|
+
if n > 10:
|
|
363
|
+
raise ValueError("only 10 Tableau colors are available")
|
|
364
|
+
pal = _TABLEAU[:n]
|
|
365
|
+
|
|
366
|
+
elif kind == "distinct":
|
|
367
|
+
if n > 15:
|
|
368
|
+
raise ValueError("only 15 distinct colors are available")
|
|
369
|
+
pal = _DISTINCT[:n]
|
|
370
|
+
|
|
371
|
+
elif kind == "manual.s":
|
|
372
|
+
anchors = list(pal) + list(
|
|
373
|
+
end_pal if isinstance(end_pal, list) else [end_pal])
|
|
374
|
+
pal = _ramp(anchors, n)
|
|
375
|
+
|
|
376
|
+
else: # manual.q
|
|
377
|
+
from .plotly_utils import to_hex
|
|
378
|
+
pal = [to_hex(c1) for c1 in pal]
|
|
379
|
+
n = len(pal)
|
|
380
|
+
|
|
381
|
+
if transparency > 0:
|
|
382
|
+
from .plotly_utils import make_trans
|
|
383
|
+
pal = [make_trans(col, 1 - transparency) for col in pal]
|
|
384
|
+
|
|
385
|
+
if not quiet:
|
|
386
|
+
_print_table(pal, kind)
|
|
387
|
+
return pal
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def _print_table(pal, kind):
|
|
391
|
+
from .plotly_utils import to_hex, hex_to_rgb3
|
|
392
|
+
print()
|
|
393
|
+
print(" color r g b")
|
|
394
|
+
print("-----------------------------")
|
|
395
|
+
for i, col in enumerate(pal, 1):
|
|
396
|
+
r, g, b = hex_to_rgb3(to_hex(col))
|
|
397
|
+
print("{:>2} {:<9}{:>4} {:>4} {:>4}".format(
|
|
398
|
+
i, col, r, g, b))
|
|
399
|
+
print()
|