matplotly 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.
- matplotly/__init__.py +124 -0
- matplotly/_api.py +984 -0
- matplotly/_code_gen.py +1793 -0
- matplotly/_commands.py +109 -0
- matplotly/_introspect.py +1197 -0
- matplotly/_profiles.py +241 -0
- matplotly/_renderer.py +79 -0
- matplotly/_style_import.py +155 -0
- matplotly/_types.py +31 -0
- matplotly/panels/__init__.py +37 -0
- matplotly/panels/_bar.py +788 -0
- matplotly/panels/_base.py +38 -0
- matplotly/panels/_color_utils.py +221 -0
- matplotly/panels/_distribution.py +1605 -0
- matplotly/panels/_errorbar.py +652 -0
- matplotly/panels/_fill.py +90 -0
- matplotly/panels/_global.py +1507 -0
- matplotly/panels/_heatmap.py +898 -0
- matplotly/panels/_histogram.py +938 -0
- matplotly/panels/_line.py +709 -0
- matplotly/panels/_marginal.py +944 -0
- matplotly/panels/_scatter.py +428 -0
- matplotly/panels/_subplot.py +846 -0
- matplotly-0.1.0.dist-info/METADATA +120 -0
- matplotly-0.1.0.dist-info/RECORD +27 -0
- matplotly-0.1.0.dist-info/WHEEL +4 -0
- matplotly-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
"""Scatter plot controls — collapsible per-collection sections with compact color UI."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import ipywidgets as widgets
|
|
5
|
+
import numpy as np
|
|
6
|
+
from matplotlib.colors import to_hex
|
|
7
|
+
from matplotlib.markers import MarkerStyle
|
|
8
|
+
|
|
9
|
+
from .._commands import Command
|
|
10
|
+
from .._types import ArtistGroup
|
|
11
|
+
from ._base import ArtistPanel
|
|
12
|
+
from ._color_utils import (
|
|
13
|
+
_DW, _NW, _SN,
|
|
14
|
+
_get_palette_colors, _make_color_dot, _refresh_legend, _slider_num,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ScatterPanel(ArtistPanel):
|
|
19
|
+
_plot_number: int = 0 # set by _api.py before build()
|
|
20
|
+
|
|
21
|
+
def build(self) -> widgets.Widget:
|
|
22
|
+
coll = self._group.artists[0]
|
|
23
|
+
current_label = coll.get_label() or self._group.label
|
|
24
|
+
|
|
25
|
+
fc = coll.get_facecolor()
|
|
26
|
+
try:
|
|
27
|
+
current_color = to_hex(fc[0]) if len(fc) > 0 else "#1f77b4"
|
|
28
|
+
except Exception:
|
|
29
|
+
current_color = "#1f77b4"
|
|
30
|
+
|
|
31
|
+
# --- Collapsible header ---
|
|
32
|
+
num = self._plot_number or ""
|
|
33
|
+
header_prefix = f"Scatter {num}: " if num else ""
|
|
34
|
+
self._header_prefix = header_prefix
|
|
35
|
+
|
|
36
|
+
self._color_indicator = widgets.HTML(_make_color_dot(current_color))
|
|
37
|
+
|
|
38
|
+
toggle_btn = widgets.Button(
|
|
39
|
+
description=f" {header_prefix}{current_label}",
|
|
40
|
+
icon="chevron-right",
|
|
41
|
+
layout=widgets.Layout(width='100%', height='28px'))
|
|
42
|
+
toggle_btn.style.button_color = '#f0f0f0'
|
|
43
|
+
toggle_btn.style.font_weight = 'bold'
|
|
44
|
+
self._toggle_btn = toggle_btn
|
|
45
|
+
|
|
46
|
+
header_row = widgets.HBox(
|
|
47
|
+
[self._color_indicator, toggle_btn],
|
|
48
|
+
layout=widgets.Layout(align_items='center', gap='4px'))
|
|
49
|
+
|
|
50
|
+
# --- Controls (collapsed by default) ---
|
|
51
|
+
controls = self._build_controls(coll, current_label, current_color)
|
|
52
|
+
controls_box = widgets.VBox(
|
|
53
|
+
controls,
|
|
54
|
+
layout=widgets.Layout(display='none', padding='2px 0 4px 12px'))
|
|
55
|
+
self._controls_box = controls_box
|
|
56
|
+
self._is_expanded = False
|
|
57
|
+
|
|
58
|
+
def _toggle(btn, c=coll):
|
|
59
|
+
self._is_expanded = not self._is_expanded
|
|
60
|
+
lbl = c.get_label() or self._group.label
|
|
61
|
+
if self._is_expanded:
|
|
62
|
+
controls_box.layout.display = ''
|
|
63
|
+
toggle_btn.icon = "chevron-down"
|
|
64
|
+
toggle_btn.description = f" {self._header_prefix}{lbl}"
|
|
65
|
+
else:
|
|
66
|
+
controls_box.layout.display = 'none'
|
|
67
|
+
toggle_btn.icon = "chevron-right"
|
|
68
|
+
toggle_btn.description = f" {self._header_prefix}{lbl}"
|
|
69
|
+
toggle_btn.on_click(_toggle)
|
|
70
|
+
|
|
71
|
+
return widgets.VBox(
|
|
72
|
+
[header_row, controls_box],
|
|
73
|
+
layout=widgets.Layout(
|
|
74
|
+
border='1px solid #ddd', border_radius='4px',
|
|
75
|
+
margin='2px 0', padding='2px'))
|
|
76
|
+
|
|
77
|
+
_on_label_changed = None # callback set by _api.py for legend label sync
|
|
78
|
+
|
|
79
|
+
def _build_controls(self, coll, current_label, current_color):
|
|
80
|
+
"""Build all controls for this scatter collection."""
|
|
81
|
+
controls = []
|
|
82
|
+
self._edge_manual = False # track if user manually changed edge color
|
|
83
|
+
|
|
84
|
+
# Set initial edge color to match face color
|
|
85
|
+
coll.set_edgecolor(current_color)
|
|
86
|
+
|
|
87
|
+
# --- Name ---
|
|
88
|
+
name_field = widgets.Text(
|
|
89
|
+
value=current_label, description="Name:",
|
|
90
|
+
style={"description_width": _DW},
|
|
91
|
+
layout=widgets.Layout(width="95%"))
|
|
92
|
+
|
|
93
|
+
def _on_name(change, c=coll):
|
|
94
|
+
old_label = c.get_label()
|
|
95
|
+
new_label = change["new"]
|
|
96
|
+
self._stack.execute(
|
|
97
|
+
Command(c, "label", old_label, new_label,
|
|
98
|
+
description=f"{self._group.label} label"))
|
|
99
|
+
pfx = self._header_prefix
|
|
100
|
+
icon = "chevron-down" if self._is_expanded else "chevron-right"
|
|
101
|
+
self._toggle_btn.icon = icon
|
|
102
|
+
self._toggle_btn.description = f" {pfx}{new_label}"
|
|
103
|
+
_refresh_legend(c.axes)
|
|
104
|
+
if self._on_label_changed is not None:
|
|
105
|
+
self._on_label_changed()
|
|
106
|
+
self._canvas.force_redraw()
|
|
107
|
+
name_field.observe(_on_name, names="value")
|
|
108
|
+
controls.append(name_field)
|
|
109
|
+
|
|
110
|
+
# --- Color (facecolor) ---
|
|
111
|
+
controls.append(self._build_color_section(
|
|
112
|
+
coll, current_color, "Color:", "facecolor",
|
|
113
|
+
getter=lambda c: to_hex(c.get_facecolor()[0]) if len(c.get_facecolor()) > 0 else "#1f77b4",
|
|
114
|
+
setter_name="set_facecolor",
|
|
115
|
+
is_primary=True))
|
|
116
|
+
|
|
117
|
+
# --- Edge color ---
|
|
118
|
+
controls.append(self._build_color_section(
|
|
119
|
+
coll, current_color, "Edge:", "edgecolor",
|
|
120
|
+
getter=lambda c: to_hex(c.get_edgecolor()[0]) if len(c.get_edgecolor()) > 0 else "#000000",
|
|
121
|
+
setter_name="set_edgecolor",
|
|
122
|
+
is_primary=False,
|
|
123
|
+
is_edge=True))
|
|
124
|
+
|
|
125
|
+
# --- Size ---
|
|
126
|
+
sizes = coll.get_sizes()
|
|
127
|
+
avg_size = float(np.mean(sizes)) if len(sizes) > 0 else 20.0
|
|
128
|
+
size_sl = widgets.FloatSlider(
|
|
129
|
+
value=round(avg_size, 1), min=1, max=200, step=1,
|
|
130
|
+
description="Size:", style=_SN)
|
|
131
|
+
|
|
132
|
+
def _size_cb(change, c=coll):
|
|
133
|
+
old = c.get_sizes().copy()
|
|
134
|
+
new_val = change["new"]
|
|
135
|
+
n_pts = len(c.get_offsets())
|
|
136
|
+
def _apply():
|
|
137
|
+
c.set_sizes([new_val] * n_pts)
|
|
138
|
+
def _revert():
|
|
139
|
+
c.set_sizes(old)
|
|
140
|
+
self._stack.execute(
|
|
141
|
+
Command(c, "sizes", old, new_val,
|
|
142
|
+
apply_fn=_apply, revert_fn=_revert,
|
|
143
|
+
description=f"{self._group.label} size"))
|
|
144
|
+
_refresh_legend(c.axes)
|
|
145
|
+
self._canvas.force_redraw()
|
|
146
|
+
size_sl.observe(_size_cb, names="value")
|
|
147
|
+
controls.append(_slider_num(size_sl))
|
|
148
|
+
|
|
149
|
+
# --- Alpha ---
|
|
150
|
+
alpha_val = coll.get_alpha()
|
|
151
|
+
alpha_sl = widgets.FloatSlider(
|
|
152
|
+
value=round(alpha_val if alpha_val is not None else 1.0, 2),
|
|
153
|
+
min=0, max=1, step=0.05, description="Alpha:", style=_SN)
|
|
154
|
+
|
|
155
|
+
def _alpha_cb(change, c=coll):
|
|
156
|
+
self._stack.execute(
|
|
157
|
+
Command(c, "alpha", c.get_alpha(), change["new"],
|
|
158
|
+
description=f"{self._group.label} alpha"))
|
|
159
|
+
_refresh_legend(c.axes)
|
|
160
|
+
self._canvas.force_redraw()
|
|
161
|
+
alpha_sl.observe(_alpha_cb, names="value")
|
|
162
|
+
controls.append(_slider_num(alpha_sl))
|
|
163
|
+
|
|
164
|
+
# --- Marker ---
|
|
165
|
+
markers = [("circle", "o"), ("square", "s"), ("triangle", "^"),
|
|
166
|
+
("diamond", "D"), ("plus", "+"), ("x", "x"),
|
|
167
|
+
("star", "*"), ("point", ".")]
|
|
168
|
+
marker_dd = widgets.Dropdown(
|
|
169
|
+
options=markers, value="o", description="Marker:",
|
|
170
|
+
style=_SN, layout=widgets.Layout(width="150px"))
|
|
171
|
+
|
|
172
|
+
def _marker_cb(change, c=coll):
|
|
173
|
+
old_paths = c.get_paths()
|
|
174
|
+
new_marker = MarkerStyle(change["new"])
|
|
175
|
+
new_path = new_marker.get_path().transformed(
|
|
176
|
+
new_marker.get_transform())
|
|
177
|
+
def _apply():
|
|
178
|
+
c.set_paths([new_path])
|
|
179
|
+
def _revert():
|
|
180
|
+
c.set_paths(old_paths)
|
|
181
|
+
self._stack.execute(
|
|
182
|
+
Command(c, "paths", old_paths, change["new"],
|
|
183
|
+
apply_fn=_apply, revert_fn=_revert,
|
|
184
|
+
description=f"{self._group.label} marker"))
|
|
185
|
+
_refresh_legend(c.axes)
|
|
186
|
+
self._canvas.force_redraw()
|
|
187
|
+
marker_dd.observe(_marker_cb, names="value")
|
|
188
|
+
controls.append(marker_dd)
|
|
189
|
+
|
|
190
|
+
# --- Edge width ---
|
|
191
|
+
lw = coll.get_linewidths()
|
|
192
|
+
edge_w_sl = widgets.FloatSlider(
|
|
193
|
+
value=round(float(lw[0]) if len(lw) > 0 else 1.0, 2),
|
|
194
|
+
min=0, max=5, step=0.1, description="Edge w:", style=_SN)
|
|
195
|
+
|
|
196
|
+
def _ew_cb(change, c=coll):
|
|
197
|
+
old = c.get_linewidths().copy()
|
|
198
|
+
new_val = change["new"]
|
|
199
|
+
def _apply():
|
|
200
|
+
c.set_linewidths([new_val])
|
|
201
|
+
def _revert():
|
|
202
|
+
c.set_linewidths(old)
|
|
203
|
+
self._stack.execute(
|
|
204
|
+
Command(c, "linewidths", old, new_val,
|
|
205
|
+
apply_fn=_apply, revert_fn=_revert,
|
|
206
|
+
description=f"{self._group.label} edge width"))
|
|
207
|
+
_refresh_legend(c.axes)
|
|
208
|
+
self._canvas.force_redraw()
|
|
209
|
+
edge_w_sl.observe(_ew_cb, names="value")
|
|
210
|
+
controls.append(_slider_num(edge_w_sl))
|
|
211
|
+
|
|
212
|
+
return controls
|
|
213
|
+
|
|
214
|
+
def _build_color_section(self, coll, current_color, label, prop_name,
|
|
215
|
+
getter, setter_name, is_primary,
|
|
216
|
+
is_edge=False):
|
|
217
|
+
"""Color section: click swatch -> palette swatches + expand + colorwheel.
|
|
218
|
+
|
|
219
|
+
Mirrors LinePanel._build_color_section. If is_primary, exposes
|
|
220
|
+
self._update_color and self._update_palette for ColormapPanel.
|
|
221
|
+
"""
|
|
222
|
+
color_btn = widgets.Button(
|
|
223
|
+
layout=widgets.Layout(width='28px', height='28px',
|
|
224
|
+
padding='0', min_width='28px'),
|
|
225
|
+
tooltip="Click to choose color")
|
|
226
|
+
color_btn.style.button_color = current_color
|
|
227
|
+
|
|
228
|
+
color_row = widgets.HBox(
|
|
229
|
+
[widgets.Label(label, layout=widgets.Layout(width='42px')),
|
|
230
|
+
color_btn],
|
|
231
|
+
layout=widgets.Layout(align_items='center', gap='4px'))
|
|
232
|
+
|
|
233
|
+
# --- Palette: 10 swatches (compact row) + 10 more (expanded row) ---
|
|
234
|
+
_cmap_name = ["tab10"]
|
|
235
|
+
|
|
236
|
+
def _make_swatches(colors):
|
|
237
|
+
btns = []
|
|
238
|
+
for c in colors:
|
|
239
|
+
b = widgets.Button(
|
|
240
|
+
layout=widgets.Layout(width="18px", height="16px",
|
|
241
|
+
padding="0", margin="1px",
|
|
242
|
+
min_width="18px"))
|
|
243
|
+
b.style.button_color = c
|
|
244
|
+
btns.append(b)
|
|
245
|
+
return btns
|
|
246
|
+
|
|
247
|
+
colors_10 = _get_palette_colors("tab10", 10)
|
|
248
|
+
swatch_buttons = _make_swatches(colors_10)
|
|
249
|
+
colors_20 = _get_palette_colors("tab10", 20)
|
|
250
|
+
extra_buttons = _make_swatches(colors_20[10:])
|
|
251
|
+
|
|
252
|
+
_icon_css = widgets.HTML(
|
|
253
|
+
'<style>'
|
|
254
|
+
'.pb-swatch-btn button {'
|
|
255
|
+
' padding:0 !important;'
|
|
256
|
+
' min-width:0 !important;'
|
|
257
|
+
' overflow:hidden !important;'
|
|
258
|
+
'}'
|
|
259
|
+
'.pb-swatch-btn .fa {'
|
|
260
|
+
' font-size:9px !important;'
|
|
261
|
+
' position:relative !important;'
|
|
262
|
+
' top:-7px !important;'
|
|
263
|
+
'}'
|
|
264
|
+
'</style>')
|
|
265
|
+
|
|
266
|
+
expand_btn = widgets.Button(
|
|
267
|
+
icon="plus", tooltip="Show more colors",
|
|
268
|
+
layout=widgets.Layout(width="18px", height="16px",
|
|
269
|
+
padding="0", min_width="18px",
|
|
270
|
+
margin="1px"))
|
|
271
|
+
expand_btn.style.button_color = "#e0e0e0"
|
|
272
|
+
expand_btn.add_class("pb-swatch-btn")
|
|
273
|
+
|
|
274
|
+
palette_btn = widgets.Button(
|
|
275
|
+
icon="paint-brush", tooltip="Custom color...",
|
|
276
|
+
layout=widgets.Layout(width="18px", height="16px",
|
|
277
|
+
padding="0", min_width="18px",
|
|
278
|
+
margin="1px"))
|
|
279
|
+
palette_btn.style.button_color = "#e8e8e8"
|
|
280
|
+
palette_btn.add_class("pb-swatch-btn")
|
|
281
|
+
|
|
282
|
+
_picker_cls = f"pb-picker-{id(coll)}-{prop_name}"
|
|
283
|
+
picker = widgets.ColorPicker(
|
|
284
|
+
value=current_color, concise=True,
|
|
285
|
+
layout=widgets.Layout(width="1px", height="1px",
|
|
286
|
+
overflow="hidden", padding="0",
|
|
287
|
+
margin="0", border="0"))
|
|
288
|
+
picker.add_class(_picker_cls)
|
|
289
|
+
|
|
290
|
+
_js_out = widgets.Output(
|
|
291
|
+
layout=widgets.Layout(height="0px", overflow="hidden"))
|
|
292
|
+
|
|
293
|
+
def _on_palette_btn(b):
|
|
294
|
+
with _js_out:
|
|
295
|
+
_js_out.clear_output()
|
|
296
|
+
from IPython.display import display as ipy_display, Javascript
|
|
297
|
+
ipy_display(Javascript(
|
|
298
|
+
"setTimeout(function(){"
|
|
299
|
+
"var el=document.querySelector('.%s input[type=\"color\"]');"
|
|
300
|
+
"if(el)el.click();"
|
|
301
|
+
"},150);" % _picker_cls))
|
|
302
|
+
palette_btn.on_click(_on_palette_btn)
|
|
303
|
+
|
|
304
|
+
extra_row = widgets.HBox(
|
|
305
|
+
extra_buttons,
|
|
306
|
+
layout=widgets.Layout(display='none', padding='1px 0 0 0',
|
|
307
|
+
align_items='center', gap='1px'))
|
|
308
|
+
|
|
309
|
+
main_row = widgets.HBox(
|
|
310
|
+
swatch_buttons + [expand_btn, palette_btn, picker, _icon_css,
|
|
311
|
+
_js_out],
|
|
312
|
+
layout=widgets.Layout(align_items='center', gap='1px'))
|
|
313
|
+
|
|
314
|
+
palette_panel = widgets.VBox(
|
|
315
|
+
[main_row, extra_row],
|
|
316
|
+
layout=widgets.Layout(display='none', padding='2px 0 0 0'))
|
|
317
|
+
|
|
318
|
+
# --- Sync logic ---
|
|
319
|
+
_updating = [False]
|
|
320
|
+
|
|
321
|
+
def _sync_controls(hex_val):
|
|
322
|
+
"""Update all visual controls without triggering callbacks."""
|
|
323
|
+
_updating[0] = True
|
|
324
|
+
try:
|
|
325
|
+
color_btn.style.button_color = hex_val
|
|
326
|
+
picker.value = hex_val
|
|
327
|
+
if is_primary:
|
|
328
|
+
self._color_indicator.value = _make_color_dot(hex_val)
|
|
329
|
+
finally:
|
|
330
|
+
_updating[0] = False
|
|
331
|
+
|
|
332
|
+
def _apply(hex_val, c=coll):
|
|
333
|
+
old = getattr(c, f"get_{prop_name}")().copy()
|
|
334
|
+
setter = getattr(c, setter_name)
|
|
335
|
+
def _do_apply():
|
|
336
|
+
setter(hex_val)
|
|
337
|
+
def _do_revert():
|
|
338
|
+
setter(old)
|
|
339
|
+
self._stack.execute(
|
|
340
|
+
Command(c, prop_name, old, hex_val,
|
|
341
|
+
apply_fn=_do_apply, revert_fn=_do_revert,
|
|
342
|
+
description=f"{self._group.label} {prop_name}"))
|
|
343
|
+
_refresh_legend(c.axes)
|
|
344
|
+
if is_primary and hasattr(self, '_marginals'):
|
|
345
|
+
self._marginals.sync_colors()
|
|
346
|
+
# Sync edge color to match face color (unless manually overridden)
|
|
347
|
+
if is_primary and not self._edge_manual:
|
|
348
|
+
c.set_edgecolor(hex_val)
|
|
349
|
+
if hasattr(self, '_sync_edge_ui'):
|
|
350
|
+
self._sync_edge_ui(hex_val)
|
|
351
|
+
if is_edge:
|
|
352
|
+
self._edge_manual = True
|
|
353
|
+
self._canvas.force_redraw()
|
|
354
|
+
|
|
355
|
+
# Wire swatch clicks
|
|
356
|
+
def _wire_swatch(btn):
|
|
357
|
+
def _on_swatch(b, _btn=btn):
|
|
358
|
+
c = _btn.style.button_color
|
|
359
|
+
_sync_controls(c)
|
|
360
|
+
_apply(c)
|
|
361
|
+
btn.on_click(_on_swatch)
|
|
362
|
+
for b in swatch_buttons + extra_buttons:
|
|
363
|
+
_wire_swatch(b)
|
|
364
|
+
|
|
365
|
+
# Expand / collapse extra row
|
|
366
|
+
def _on_expand(b):
|
|
367
|
+
cname = _cmap_name[0]
|
|
368
|
+
if extra_row.layout.display == 'none':
|
|
369
|
+
c20 = _get_palette_colors(cname, 20)
|
|
370
|
+
for i, btn in enumerate(swatch_buttons):
|
|
371
|
+
btn.style.button_color = c20[i]
|
|
372
|
+
for i, btn in enumerate(extra_buttons):
|
|
373
|
+
btn.style.button_color = c20[10 + i]
|
|
374
|
+
extra_row.layout.display = ''
|
|
375
|
+
expand_btn.icon = 'minus'
|
|
376
|
+
expand_btn.tooltip = 'Show fewer colors'
|
|
377
|
+
else:
|
|
378
|
+
c10 = _get_palette_colors(cname, 10)
|
|
379
|
+
for i, btn in enumerate(swatch_buttons):
|
|
380
|
+
btn.style.button_color = c10[i]
|
|
381
|
+
extra_row.layout.display = 'none'
|
|
382
|
+
expand_btn.icon = 'plus'
|
|
383
|
+
expand_btn.tooltip = 'Show more colors'
|
|
384
|
+
expand_btn.on_click(_on_expand)
|
|
385
|
+
|
|
386
|
+
# Picker changes
|
|
387
|
+
def _from_picker(change):
|
|
388
|
+
if _updating[0]:
|
|
389
|
+
return
|
|
390
|
+
_sync_controls(change["new"])
|
|
391
|
+
_apply(change["new"])
|
|
392
|
+
picker.observe(_from_picker, names="value")
|
|
393
|
+
|
|
394
|
+
# Toggle palette panel
|
|
395
|
+
def _toggle_palette(btn):
|
|
396
|
+
if palette_panel.layout.display == 'none':
|
|
397
|
+
palette_panel.layout.display = ''
|
|
398
|
+
else:
|
|
399
|
+
palette_panel.layout.display = 'none'
|
|
400
|
+
color_btn.on_click(_toggle_palette)
|
|
401
|
+
|
|
402
|
+
# Edge color UI sync — store so primary color can update it
|
|
403
|
+
if is_edge:
|
|
404
|
+
self._sync_edge_ui = _sync_controls
|
|
405
|
+
|
|
406
|
+
# External update hooks (used by ColormapPanel) — primary color only
|
|
407
|
+
if is_primary:
|
|
408
|
+
self._update_color = _sync_controls
|
|
409
|
+
|
|
410
|
+
def _ext_update_palette(cmap_name):
|
|
411
|
+
_cmap_name[0] = cmap_name
|
|
412
|
+
is_expanded = extra_row.layout.display != 'none'
|
|
413
|
+
if is_expanded:
|
|
414
|
+
c20 = _get_palette_colors(cmap_name, 20)
|
|
415
|
+
for i, btn in enumerate(swatch_buttons):
|
|
416
|
+
btn.style.button_color = c20[i]
|
|
417
|
+
for i, btn in enumerate(extra_buttons):
|
|
418
|
+
btn.style.button_color = c20[10 + i]
|
|
419
|
+
else:
|
|
420
|
+
c10 = _get_palette_colors(cmap_name, 10)
|
|
421
|
+
for i, btn in enumerate(swatch_buttons):
|
|
422
|
+
btn.style.button_color = c10[i]
|
|
423
|
+
c20 = _get_palette_colors(cmap_name, 20)
|
|
424
|
+
for i, btn in enumerate(extra_buttons):
|
|
425
|
+
btn.style.button_color = c20[10 + i]
|
|
426
|
+
self._update_palette = _ext_update_palette
|
|
427
|
+
|
|
428
|
+
return widgets.VBox([color_row, palette_panel])
|