syd 0.1.6__py3-none-any.whl → 0.1.7__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.
- syd/__init__.py +3 -3
- syd/flask_deployment/__init__.py +1 -0
- syd/flask_deployment/components.py +376 -363
- syd/flask_deployment/deployer.py +247 -283
- syd/flask_deployment/static/css/viewer.css +82 -0
- syd/flask_deployment/static/js/viewer.js +174 -0
- syd/flask_deployment/templates/base.html +23 -20
- syd/flask_deployment/templates/viewer.html +49 -95
- syd/flask_deployment/testing_principles.md +300 -0
- syd/notebook_deployment/__init__.py +1 -1
- syd/notebook_deployment/_ipympl_deployer.py +258 -0
- syd/notebook_deployment/deployer.py +126 -50
- syd/notebook_deployment/widgets.py +142 -69
- syd/parameters.py +93 -180
- syd/plotly_deployment/__init__.py +1 -0
- syd/plotly_deployment/components.py +531 -0
- syd/plotly_deployment/deployer.py +376 -0
- syd/{interactive_viewer.py → viewer.py} +152 -188
- {syd-0.1.6.dist-info → syd-0.1.7.dist-info}/METADATA +26 -12
- syd-0.1.7.dist-info/RECORD +22 -0
- syd/flask_deployment/static/css/styles.css +0 -39
- syd/flask_deployment/static/js/components.js +0 -51
- syd-0.1.6.dist-info/RECORD +0 -18
- {syd-0.1.6.dist-info → syd-0.1.7.dist-info}/WHEEL +0 -0
- {syd-0.1.6.dist-info → syd-0.1.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -23,6 +23,10 @@ class _NoUpdate:
|
|
|
23
23
|
cls._instance = super().__new__(cls)
|
|
24
24
|
return cls._instance
|
|
25
25
|
|
|
26
|
+
def __eq__(self, other):
|
|
27
|
+
"""This makes sure all comparisons of _NoUpdate objects return True"""
|
|
28
|
+
return isinstance(other, _NoUpdate)
|
|
29
|
+
|
|
26
30
|
|
|
27
31
|
# Create the singleton instance
|
|
28
32
|
_NO_UPDATE = _NoUpdate()
|
|
@@ -32,7 +36,7 @@ def validate_parameter_operation(
|
|
|
32
36
|
operation: str, parameter_type: Union[ParameterType, ActionType]
|
|
33
37
|
) -> Callable:
|
|
34
38
|
"""
|
|
35
|
-
Decorator that validates parameter operations for the
|
|
39
|
+
Decorator that validates parameter operations for the viewer class.
|
|
36
40
|
|
|
37
41
|
This decorator ensures that:
|
|
38
42
|
1. The operation type matches the method name (add/update)
|
|
@@ -72,7 +76,7 @@ def validate_parameter_operation(
|
|
|
72
76
|
)
|
|
73
77
|
|
|
74
78
|
@wraps(func)
|
|
75
|
-
def wrapper(self: "
|
|
79
|
+
def wrapper(self: "Viewer", name: Any, *args, **kwargs):
|
|
76
80
|
# Validate parameter name is a string
|
|
77
81
|
if not isinstance(name, str):
|
|
78
82
|
if operation == "add":
|
|
@@ -112,9 +116,9 @@ def validate_parameter_operation(
|
|
|
112
116
|
return func(self, name, *args, **kwargs)
|
|
113
117
|
except Exception as e:
|
|
114
118
|
if operation == "add":
|
|
115
|
-
raise ParameterAddError(name, parameter_type.name, str(e))
|
|
119
|
+
raise ParameterAddError(name, parameter_type.name, str(e))
|
|
116
120
|
elif operation == "update":
|
|
117
|
-
raise ParameterUpdateError(name, parameter_type.name, str(e))
|
|
121
|
+
raise ParameterUpdateError(name, parameter_type.name, str(e))
|
|
118
122
|
else:
|
|
119
123
|
raise e
|
|
120
124
|
|
|
@@ -123,7 +127,7 @@ def validate_parameter_operation(
|
|
|
123
127
|
return decorator
|
|
124
128
|
|
|
125
129
|
|
|
126
|
-
class
|
|
130
|
+
class Viewer:
|
|
127
131
|
"""
|
|
128
132
|
Base class for creating interactive matplotlib figures with GUI controls.
|
|
129
133
|
|
|
@@ -138,7 +142,7 @@ class InteractiveViewer:
|
|
|
138
142
|
|
|
139
143
|
Examples
|
|
140
144
|
--------
|
|
141
|
-
>>> class MyViewer(
|
|
145
|
+
>>> class MyViewer(Viewer):
|
|
142
146
|
... def plot(self, state: Dict[str, Any]):
|
|
143
147
|
... fig = plt.figure()
|
|
144
148
|
... plt.plot([0, state['x']])
|
|
@@ -154,7 +158,6 @@ class InteractiveViewer:
|
|
|
154
158
|
|
|
155
159
|
parameters: Dict[str, Parameter]
|
|
156
160
|
callbacks: Dict[str, List[Callable]]
|
|
157
|
-
state: Dict[str, Any]
|
|
158
161
|
_app_deployed: bool
|
|
159
162
|
_in_callbacks: bool
|
|
160
163
|
|
|
@@ -162,15 +165,16 @@ class InteractiveViewer:
|
|
|
162
165
|
instance = super().__new__(cls)
|
|
163
166
|
instance.parameters = {}
|
|
164
167
|
instance.callbacks = {}
|
|
165
|
-
instance.state = {}
|
|
166
168
|
instance._app_deployed = False
|
|
167
169
|
instance._in_callbacks = False
|
|
168
170
|
return instance
|
|
169
171
|
|
|
170
|
-
|
|
172
|
+
@property
|
|
173
|
+
def state(self) -> Dict[str, Any]:
|
|
171
174
|
"""
|
|
172
175
|
Get the current values of all parameters.
|
|
173
176
|
|
|
177
|
+
|
|
174
178
|
Returns
|
|
175
179
|
-------
|
|
176
180
|
dict
|
|
@@ -180,10 +184,14 @@ class InteractiveViewer:
|
|
|
180
184
|
--------
|
|
181
185
|
>>> viewer.add_float('x', value=1.0, min_value=0, max_value=10)
|
|
182
186
|
>>> viewer.add_text('label', value='data')
|
|
183
|
-
>>> viewer.
|
|
187
|
+
>>> viewer.state
|
|
184
188
|
{'x': 1.0, 'label': 'data'}
|
|
185
189
|
"""
|
|
186
|
-
return {
|
|
190
|
+
return {
|
|
191
|
+
name: param.value
|
|
192
|
+
for name, param in self.parameters.items()
|
|
193
|
+
if not param._is_action
|
|
194
|
+
}
|
|
187
195
|
|
|
188
196
|
def plot(self, state: Dict[str, Any]) -> Figure:
|
|
189
197
|
"""Create and return a matplotlib figure.
|
|
@@ -192,14 +200,14 @@ class InteractiveViewer:
|
|
|
192
200
|
|
|
193
201
|
1. Call set_plot() with your plotting function
|
|
194
202
|
This will look like this:
|
|
195
|
-
>>> def plot(
|
|
203
|
+
>>> def plot(state):
|
|
196
204
|
>>> ... generate figure, plot stuff ...
|
|
197
205
|
>>> return fig
|
|
198
206
|
>>> viewer.set_plot(plot))
|
|
199
207
|
|
|
200
|
-
2. Subclass
|
|
208
|
+
2. Subclass Viewer and override this method
|
|
201
209
|
This will look like this:
|
|
202
|
-
>>> class YourViewer(
|
|
210
|
+
>>> class YourViewer(Viewer):
|
|
203
211
|
>>> def plot(self, state):
|
|
204
212
|
>>> ... generate figure, plot stuff ...
|
|
205
213
|
>>> return fig
|
|
@@ -223,7 +231,7 @@ class InteractiveViewer:
|
|
|
223
231
|
"""
|
|
224
232
|
raise NotImplementedError(
|
|
225
233
|
"Plot method not implemented. Either subclass "
|
|
226
|
-
"
|
|
234
|
+
"Viewer and override plot(), or use "
|
|
227
235
|
"set_plot() to provide a plotting function."
|
|
228
236
|
)
|
|
229
237
|
|
|
@@ -234,15 +242,35 @@ class InteractiveViewer:
|
|
|
234
242
|
def deploy(self, env: str = "notebook", **kwargs):
|
|
235
243
|
"""Deploy the app in a notebook or standalone environment"""
|
|
236
244
|
if env == "notebook":
|
|
237
|
-
from .notebook_deployment import
|
|
245
|
+
from .notebook_deployment import NotebookDeployer
|
|
238
246
|
|
|
239
|
-
deployer =
|
|
247
|
+
deployer = NotebookDeployer(self, **kwargs)
|
|
240
248
|
deployer.deploy()
|
|
249
|
+
return self
|
|
250
|
+
|
|
251
|
+
elif env == "plotly":
|
|
252
|
+
from .plotly_deployment import PlotlyDeployer
|
|
253
|
+
|
|
254
|
+
deployer = PlotlyDeployer(self, **kwargs)
|
|
255
|
+
deployer.deploy(mode="server")
|
|
256
|
+
return self
|
|
257
|
+
|
|
258
|
+
elif env == "plotly-inline":
|
|
259
|
+
from .plotly_deployment import PlotlyDeployer
|
|
241
260
|
|
|
261
|
+
deployer = PlotlyDeployer(self, **kwargs)
|
|
262
|
+
deployer.deploy(mode="notebook")
|
|
263
|
+
return self
|
|
264
|
+
|
|
265
|
+
elif env == "flask":
|
|
266
|
+
from .flask_deployment import FlaskDeployer
|
|
267
|
+
|
|
268
|
+
deployer = FlaskDeployer(self, **kwargs)
|
|
269
|
+
deployer.deploy()
|
|
242
270
|
return self
|
|
243
271
|
else:
|
|
244
272
|
raise ValueError(
|
|
245
|
-
f"Unsupported environment: {env}, only 'notebook'
|
|
273
|
+
f"Unsupported environment: {env}, only 'notebook', 'plotly', 'plotly-inline', and 'flask' are supported right now."
|
|
246
274
|
)
|
|
247
275
|
|
|
248
276
|
@contextmanager
|
|
@@ -265,7 +293,6 @@ class InteractiveViewer:
|
|
|
265
293
|
|
|
266
294
|
# Handle partial functions
|
|
267
295
|
if isinstance(func, partial):
|
|
268
|
-
# Create new partial with self as first arg if not already there
|
|
269
296
|
get_self = (
|
|
270
297
|
lambda func: hasattr(func.func, "__self__") and func.func.__self__
|
|
271
298
|
)
|
|
@@ -274,17 +301,6 @@ class InteractiveViewer:
|
|
|
274
301
|
get_self = lambda func: hasattr(func, "__self__") and func.__self__
|
|
275
302
|
get_name = lambda func: func.__name__
|
|
276
303
|
|
|
277
|
-
# Check if it's a class method
|
|
278
|
-
class_method = get_self(func) is self.__class__
|
|
279
|
-
if class_method:
|
|
280
|
-
raise ValueError(context + "Class methods are not supported.")
|
|
281
|
-
|
|
282
|
-
# Check if it's a bound method to another instance other than this one
|
|
283
|
-
if get_self(func) and get_self(func) is not self:
|
|
284
|
-
raise ValueError(
|
|
285
|
-
context + "Bound methods to other instances are not supported."
|
|
286
|
-
)
|
|
287
|
-
|
|
288
304
|
# Get function signature
|
|
289
305
|
try:
|
|
290
306
|
params = list(inspect.signature(func).parameters.values())
|
|
@@ -294,17 +310,18 @@ class InteractiveViewer:
|
|
|
294
310
|
|
|
295
311
|
# Look through params and check if there are two positional parameters (including self for bound methods)
|
|
296
312
|
bound_method = get_self(func) is self
|
|
297
|
-
positional_params = 0
|
|
313
|
+
positional_params = 0
|
|
314
|
+
required_kwargs = 0
|
|
298
315
|
optional_part = ""
|
|
299
316
|
for param in params:
|
|
300
317
|
# Check if it's a positional parameter. If it is, count it.
|
|
301
|
-
#
|
|
302
|
-
#
|
|
318
|
+
# We need at least 1 positional parameter. When we already have 1,
|
|
319
|
+
# we need to make sure any other positional parameters have defaults.
|
|
303
320
|
if param.kind in (
|
|
304
321
|
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
305
322
|
inspect.Parameter.POSITIONAL_ONLY,
|
|
306
323
|
):
|
|
307
|
-
if positional_params <
|
|
324
|
+
if positional_params < 1:
|
|
308
325
|
positional_params += 1
|
|
309
326
|
else:
|
|
310
327
|
if param.default == inspect.Parameter.empty:
|
|
@@ -317,10 +334,12 @@ class InteractiveViewer:
|
|
|
317
334
|
optional_part += (
|
|
318
335
|
f", {param.name}={param.default!r}"
|
|
319
336
|
if param.default != inspect.Parameter.empty
|
|
320
|
-
else f"
|
|
337
|
+
else f""
|
|
321
338
|
)
|
|
339
|
+
if param.default == inspect.Parameter.empty:
|
|
340
|
+
required_kwargs += 1
|
|
322
341
|
|
|
323
|
-
if positional_params !=
|
|
342
|
+
if positional_params != 1 or required_kwargs != 0:
|
|
324
343
|
func_name = get_name(func)
|
|
325
344
|
if isinstance(func, partial):
|
|
326
345
|
func_sig = str(inspect.signature(func))
|
|
@@ -330,9 +349,8 @@ class InteractiveViewer:
|
|
|
330
349
|
context
|
|
331
350
|
+ "\n"
|
|
332
351
|
+ f"Your partial function '{func_name}' has an incorrect signature.\n"
|
|
333
|
-
"Partial functions must have exactly
|
|
334
|
-
"
|
|
335
|
-
"The second parameter should be state -- a dictionary of the current state of the viewer.\n"
|
|
352
|
+
"Partial functions must have exactly one positional parameter\n"
|
|
353
|
+
"which corresponds to a dictionary of the current state of the viewer.\n"
|
|
336
354
|
"\nYour partial function effectivelylooks like this:\n"
|
|
337
355
|
f"def {func_name}{func_sig}:\n"
|
|
338
356
|
" ... your function code ..."
|
|
@@ -347,45 +365,44 @@ class InteractiveViewer:
|
|
|
347
365
|
context + "\n"
|
|
348
366
|
f"Your bound method '{func_name}{func_sig}' has an incorrect signature.\n"
|
|
349
367
|
"Bound methods must have exactly one positional parameter in addition to self.\n"
|
|
350
|
-
"The first parameter should be self
|
|
368
|
+
"The first parameter should be self (required for bound methods).\n"
|
|
351
369
|
"The second parameter should be state -- a dictionary of the current state of the viewer.\n"
|
|
352
370
|
"\nYour method looks like this:\n"
|
|
353
|
-
"class YourViewer(
|
|
371
|
+
"class YourViewer(Viewer):\n"
|
|
354
372
|
f" def {func_name}{func_sig}:\n"
|
|
355
373
|
" ... your function code ...\n"
|
|
356
374
|
"\nIt should look like this:\n"
|
|
357
|
-
"class YourViewer(
|
|
375
|
+
"class YourViewer(Viewer):\n"
|
|
358
376
|
f" def {func_name}(self, state{optional_part}):\n"
|
|
359
377
|
" ... your function code ..."
|
|
360
378
|
)
|
|
361
379
|
raise ValueError(msg)
|
|
362
380
|
else:
|
|
363
381
|
func_sig = str(inspect.signature(func))
|
|
364
|
-
|
|
382
|
+
bound_elsewhere = get_self(func) and get_self(func) is not self
|
|
383
|
+
if bound_elsewhere:
|
|
384
|
+
func_name = f"self.{func_name}"
|
|
385
|
+
func_sig = f"(self, {func_sig[1:]})"
|
|
386
|
+
add_self = True
|
|
387
|
+
else:
|
|
388
|
+
add_self = False
|
|
365
389
|
msg = (
|
|
366
390
|
context + "\n"
|
|
367
391
|
f"Your function '{func_name}{func_sig}' has an incorrect signature.\n"
|
|
368
|
-
"
|
|
369
|
-
"
|
|
370
|
-
"The second parameter should be state -- a dictionary of the current state of the viewer.\n"
|
|
392
|
+
"Functions must have exactly one positional parameter\n"
|
|
393
|
+
"which corresponds to a dictionary of the current state of the viewer.\n"
|
|
371
394
|
"\nYour function looks like this:\n"
|
|
372
395
|
f"def {func_name}{func_sig}:\n"
|
|
373
396
|
" ... your function code ...\n"
|
|
374
397
|
"\nIt should look like this:\n"
|
|
375
|
-
f"def {func_name}(
|
|
398
|
+
f"def {func_name}({'self, ' if add_self else ''}state{optional_part}):\n"
|
|
376
399
|
" ... your function code ..."
|
|
377
400
|
)
|
|
378
401
|
raise ValueError(msg)
|
|
379
402
|
|
|
380
|
-
# If
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
@wraps(func)
|
|
385
|
-
def func_with_self(*args, **kwargs):
|
|
386
|
-
return func(self, *args, **kwargs)
|
|
387
|
-
|
|
388
|
-
return func_with_self
|
|
403
|
+
# If we've made it here, the function has exactly one required positional parameter
|
|
404
|
+
# which means it's callable by the viewer.
|
|
405
|
+
return func
|
|
389
406
|
|
|
390
407
|
def perform_callbacks(self, name: str) -> bool:
|
|
391
408
|
"""Perform callbacks for all parameters that have changed"""
|
|
@@ -394,7 +411,7 @@ class InteractiveViewer:
|
|
|
394
411
|
try:
|
|
395
412
|
self._in_callbacks = True
|
|
396
413
|
if name in self.callbacks:
|
|
397
|
-
state = self.
|
|
414
|
+
state = self.state
|
|
398
415
|
for callback in self.callbacks[name]:
|
|
399
416
|
callback(state)
|
|
400
417
|
finally:
|
|
@@ -484,7 +501,7 @@ class InteractiveViewer:
|
|
|
484
501
|
Examples
|
|
485
502
|
--------
|
|
486
503
|
>>> viewer.add_text('title', value='My Plot')
|
|
487
|
-
>>> viewer.
|
|
504
|
+
>>> viewer.state['title']
|
|
488
505
|
'My Plot'
|
|
489
506
|
"""
|
|
490
507
|
try:
|
|
@@ -512,7 +529,7 @@ class InteractiveViewer:
|
|
|
512
529
|
Examples
|
|
513
530
|
--------
|
|
514
531
|
>>> viewer.add_boolean('show_grid', value=True)
|
|
515
|
-
>>> viewer.
|
|
532
|
+
>>> viewer.state['show_grid']
|
|
516
533
|
True
|
|
517
534
|
"""
|
|
518
535
|
try:
|
|
@@ -543,7 +560,7 @@ class InteractiveViewer:
|
|
|
543
560
|
--------
|
|
544
561
|
>>> viewer.add_selection('color', value='red',
|
|
545
562
|
... options=['red', 'green', 'blue'])
|
|
546
|
-
>>> viewer.
|
|
563
|
+
>>> viewer.state['color']
|
|
547
564
|
'red'
|
|
548
565
|
"""
|
|
549
566
|
try:
|
|
@@ -578,7 +595,7 @@ class InteractiveViewer:
|
|
|
578
595
|
>>> viewer.add_multiple_selection('toppings',
|
|
579
596
|
... value=['cheese'],
|
|
580
597
|
... options=['cheese', 'pepperoni', 'mushrooms'])
|
|
581
|
-
>>> viewer.
|
|
598
|
+
>>> viewer.state['toppings']
|
|
582
599
|
['cheese']
|
|
583
600
|
"""
|
|
584
601
|
try:
|
|
@@ -618,10 +635,10 @@ class InteractiveViewer:
|
|
|
618
635
|
Examples
|
|
619
636
|
--------
|
|
620
637
|
>>> viewer.add_integer('count', value=5, min_value=0, max_value=10)
|
|
621
|
-
>>> viewer.
|
|
638
|
+
>>> viewer.state['count']
|
|
622
639
|
5
|
|
623
640
|
>>> viewer.update_integer('count', value=15) # Will be clamped to 10
|
|
624
|
-
>>> viewer.
|
|
641
|
+
>>> viewer.state['count']
|
|
625
642
|
10
|
|
626
643
|
"""
|
|
627
644
|
try:
|
|
@@ -632,7 +649,7 @@ class InteractiveViewer:
|
|
|
632
649
|
max_value,
|
|
633
650
|
)
|
|
634
651
|
except Exception as e:
|
|
635
|
-
raise ParameterAddError(name, "number", str(e))
|
|
652
|
+
raise ParameterAddError(name, "number", str(e))
|
|
636
653
|
else:
|
|
637
654
|
self.parameters[name] = new_param
|
|
638
655
|
|
|
@@ -644,11 +661,12 @@ class InteractiveViewer:
|
|
|
644
661
|
value: Union[float, int],
|
|
645
662
|
min_value: Union[float, int],
|
|
646
663
|
max_value: Union[float, int],
|
|
647
|
-
step: float = 0.
|
|
664
|
+
step: float = 0.01,
|
|
648
665
|
) -> None:
|
|
649
666
|
"""
|
|
650
667
|
Add a decimal number parameter to the viewer.
|
|
651
668
|
|
|
669
|
+
|
|
652
670
|
Creates a slider in the GUI that lets users select numbers between
|
|
653
671
|
min_value and max_value. Values will be rounded to the nearest step
|
|
654
672
|
and clamped to stay within bounds.
|
|
@@ -664,16 +682,16 @@ class InteractiveViewer:
|
|
|
664
682
|
max_value : float
|
|
665
683
|
Maximum allowed value
|
|
666
684
|
step : float, optional
|
|
667
|
-
Size of each increment (default: 0.
|
|
685
|
+
Size of each increment (default: 0.01)
|
|
668
686
|
|
|
669
687
|
Examples
|
|
670
688
|
--------
|
|
671
689
|
>>> viewer.add_float('temperature', value=20.0,
|
|
672
690
|
... min_value=0.0, max_value=100.0, step=0.5)
|
|
673
|
-
>>> viewer.
|
|
691
|
+
>>> viewer.state['temperature']
|
|
674
692
|
20.0
|
|
675
693
|
>>> viewer.update_float('temperature', value=20.7) # Will round to 20.5
|
|
676
|
-
>>> viewer.
|
|
694
|
+
>>> viewer.state['temperature']
|
|
677
695
|
20.5
|
|
678
696
|
"""
|
|
679
697
|
try:
|
|
@@ -722,11 +740,11 @@ class InteractiveViewer:
|
|
|
722
740
|
>>> viewer.add_integer_range('age_range',
|
|
723
741
|
... value=(25, 35),
|
|
724
742
|
... min_value=18, max_value=100)
|
|
725
|
-
>>> viewer.
|
|
743
|
+
>>> viewer.state['age_range']
|
|
726
744
|
(25, 35)
|
|
727
745
|
>>> # Values will be swapped if low > high
|
|
728
746
|
>>> viewer.update_integer_range('age_range', value=(40, 30))
|
|
729
|
-
>>> viewer.
|
|
747
|
+
>>> viewer.state['age_range']
|
|
730
748
|
(30, 40)
|
|
731
749
|
"""
|
|
732
750
|
try:
|
|
@@ -749,7 +767,7 @@ class InteractiveViewer:
|
|
|
749
767
|
value: Tuple[Union[float, int], Union[float, int]],
|
|
750
768
|
min_value: Union[float, int],
|
|
751
769
|
max_value: Union[float, int],
|
|
752
|
-
step: float = 0.
|
|
770
|
+
step: float = 0.01,
|
|
753
771
|
) -> None:
|
|
754
772
|
"""
|
|
755
773
|
Add a range parameter for decimal numbers to the viewer.
|
|
@@ -770,18 +788,18 @@ class InteractiveViewer:
|
|
|
770
788
|
max_value : float
|
|
771
789
|
Maximum allowed value for both low and high
|
|
772
790
|
step : float, optional
|
|
773
|
-
Size of each increment (default: 0.
|
|
791
|
+
Size of each increment (default: 0.01)
|
|
774
792
|
|
|
775
793
|
Examples
|
|
776
794
|
--------
|
|
777
795
|
>>> viewer.add_float_range('price_range',
|
|
778
796
|
... value=(10.0, 20.0),
|
|
779
797
|
... min_value=0.0, max_value=100.0, step=0.5)
|
|
780
|
-
>>> viewer.
|
|
798
|
+
>>> viewer.state['price_range']
|
|
781
799
|
(10.0, 20.0)
|
|
782
800
|
>>> # Values will be rounded to nearest step
|
|
783
801
|
>>> viewer.update_float_range('price_range', value=(10.7, 19.2))
|
|
784
|
-
>>> viewer.
|
|
802
|
+
>>> viewer.state['price_range']
|
|
785
803
|
(10.5, 19.0)
|
|
786
804
|
"""
|
|
787
805
|
try:
|
|
@@ -803,15 +821,12 @@ class InteractiveViewer:
|
|
|
803
821
|
name: str,
|
|
804
822
|
*,
|
|
805
823
|
value: Union[float, int],
|
|
806
|
-
min_value: Optional[Union[float, int]] = None,
|
|
807
|
-
max_value: Optional[Union[float, int]] = None,
|
|
808
824
|
) -> None:
|
|
809
825
|
"""
|
|
810
826
|
Add an unbounded integer parameter to the viewer.
|
|
811
827
|
|
|
812
828
|
Creates a text input box in the GUI for entering whole numbers. Unlike
|
|
813
|
-
add_integer(), this allows very large numbers
|
|
814
|
-
or maximum bounds.
|
|
829
|
+
add_integer(), this allows very large numbers without bounds.
|
|
815
830
|
See :class:`~syd.parameters.UnboundedIntegerParameter` for details.
|
|
816
831
|
|
|
817
832
|
Parameters
|
|
@@ -820,29 +835,17 @@ class InteractiveViewer:
|
|
|
820
835
|
Name of the parameter (used as label in GUI)
|
|
821
836
|
value : int
|
|
822
837
|
Initial value
|
|
823
|
-
min_value : int, optional
|
|
824
|
-
Minimum allowed value (or None for no minimum)
|
|
825
|
-
max_value : int, optional
|
|
826
|
-
Maximum allowed value (or None for no maximum)
|
|
827
838
|
|
|
828
839
|
Examples
|
|
829
840
|
--------
|
|
830
|
-
>>> viewer.add_unbounded_integer('population',
|
|
831
|
-
|
|
832
|
-
... min_value=0) # No maximum
|
|
833
|
-
>>> viewer.get_state()['population']
|
|
841
|
+
>>> viewer.add_unbounded_integer('population', value=1000000)
|
|
842
|
+
>>> viewer.state['population']
|
|
834
843
|
1000000
|
|
835
|
-
>>> # Values below minimum will be clamped
|
|
836
|
-
>>> viewer.update_unbounded_integer('population', value=-5)
|
|
837
|
-
>>> viewer.get_state()['population']
|
|
838
|
-
0
|
|
839
844
|
"""
|
|
840
845
|
try:
|
|
841
846
|
new_param = ParameterType.unbounded_integer.value(
|
|
842
847
|
name,
|
|
843
848
|
value,
|
|
844
|
-
min_value,
|
|
845
|
-
max_value,
|
|
846
849
|
)
|
|
847
850
|
except Exception as e:
|
|
848
851
|
raise ParameterAddError(name, "unbounded_integer", str(e)) from e
|
|
@@ -855,16 +858,14 @@ class InteractiveViewer:
|
|
|
855
858
|
name: str,
|
|
856
859
|
*,
|
|
857
860
|
value: Union[float, int],
|
|
858
|
-
min_value: Optional[Union[float, int]] = None,
|
|
859
|
-
max_value: Optional[Union[float, int]] = None,
|
|
860
861
|
step: Optional[float] = None,
|
|
861
862
|
) -> None:
|
|
862
863
|
"""
|
|
863
864
|
Add an unbounded decimal number parameter to the viewer.
|
|
864
865
|
|
|
865
866
|
Creates a text input box in the GUI for entering numbers. Unlike add_float(),
|
|
866
|
-
this allows very large or precise numbers
|
|
867
|
-
|
|
867
|
+
this allows very large or precise numbers without bounds. Values can optionally
|
|
868
|
+
be rounded to a step size.
|
|
868
869
|
See :class:`~syd.parameters.UnboundedFloatParameter` for details.
|
|
869
870
|
|
|
870
871
|
Parameters
|
|
@@ -873,32 +874,23 @@ class InteractiveViewer:
|
|
|
873
874
|
Name of the parameter (used as label in GUI)
|
|
874
875
|
value : float
|
|
875
876
|
Initial value
|
|
876
|
-
min_value : float, optional
|
|
877
|
-
Minimum allowed value (or None for no minimum)
|
|
878
|
-
max_value : float, optional
|
|
879
|
-
Maximum allowed value (or None for no maximum)
|
|
880
877
|
step : float, optional
|
|
881
878
|
Size of each increment (or None for no rounding)
|
|
882
879
|
|
|
883
880
|
Examples
|
|
884
881
|
--------
|
|
885
|
-
>>> viewer.add_unbounded_float('wavelength',
|
|
886
|
-
|
|
887
|
-
... min_value=0.0,
|
|
888
|
-
... step=1e-9) # Round to nearest nanometer
|
|
889
|
-
>>> viewer.get_state()['wavelength']
|
|
882
|
+
>>> viewer.add_unbounded_float('wavelength', value=550e-9, step=1e-9)
|
|
883
|
+
>>> viewer.state['wavelength']
|
|
890
884
|
5.5e-07
|
|
891
885
|
>>> # Values will be rounded if step is provided
|
|
892
886
|
>>> viewer.update_unbounded_float('wavelength', value=550.7e-9)
|
|
893
|
-
>>> viewer.
|
|
887
|
+
>>> viewer.state['wavelength']
|
|
894
888
|
5.51e-07
|
|
895
889
|
"""
|
|
896
890
|
try:
|
|
897
891
|
new_param = ParameterType.unbounded_float.value(
|
|
898
892
|
name,
|
|
899
893
|
value,
|
|
900
|
-
min_value,
|
|
901
|
-
max_value,
|
|
902
894
|
step,
|
|
903
895
|
)
|
|
904
896
|
except Exception as e:
|
|
@@ -928,16 +920,19 @@ class InteractiveViewer:
|
|
|
928
920
|
label : str
|
|
929
921
|
Text to display on the button
|
|
930
922
|
callback : callable
|
|
931
|
-
Function to call when the button is clicked (takes
|
|
923
|
+
Function to call when the button is clicked (takes state as a single argument)
|
|
932
924
|
|
|
933
925
|
Examples
|
|
934
926
|
--------
|
|
935
|
-
>>> def reset_plot():
|
|
927
|
+
>>> def reset_plot(state):
|
|
936
928
|
... print("Resetting plot...")
|
|
937
929
|
>>> viewer.add_button('reset', label='Reset Plot', callback=reset_plot)
|
|
930
|
+
|
|
931
|
+
>>> def print_plot_info(state):
|
|
932
|
+
... print(f"Current plot info: {state['plot_info']}")
|
|
933
|
+
>>> viewer.add_button('print_info', label='Print Plot Info', callback=print_plot_info)
|
|
938
934
|
"""
|
|
939
935
|
try:
|
|
940
|
-
|
|
941
936
|
callback = self._prepare_function(
|
|
942
937
|
callback,
|
|
943
938
|
context="Setting button callback:",
|
|
@@ -957,7 +952,7 @@ class InteractiveViewer:
|
|
|
957
952
|
"""
|
|
958
953
|
Update a text parameter's value.
|
|
959
954
|
|
|
960
|
-
Updates a parameter created by :meth:`~syd.
|
|
955
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_text`.
|
|
961
956
|
See :class:`~syd.parameters.TextParameter` for details about value validation.
|
|
962
957
|
|
|
963
958
|
Parameters
|
|
@@ -971,11 +966,11 @@ class InteractiveViewer:
|
|
|
971
966
|
--------
|
|
972
967
|
>>> viewer.add_text('title', value='Original Title')
|
|
973
968
|
>>> viewer.update_text('title', value='New Title')
|
|
974
|
-
>>> viewer.
|
|
969
|
+
>>> viewer.state['title']
|
|
975
970
|
'New Title'
|
|
976
971
|
"""
|
|
977
972
|
updates = {}
|
|
978
|
-
if value
|
|
973
|
+
if not value == _NO_UPDATE:
|
|
979
974
|
updates["value"] = value
|
|
980
975
|
if updates:
|
|
981
976
|
self.parameters[name].update(updates)
|
|
@@ -987,7 +982,7 @@ class InteractiveViewer:
|
|
|
987
982
|
"""
|
|
988
983
|
Update a boolean parameter's value.
|
|
989
984
|
|
|
990
|
-
Updates a parameter created by :meth:`~syd.
|
|
985
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_boolean`.
|
|
991
986
|
See :class:`~syd.parameters.BooleanParameter` for details about value validation.
|
|
992
987
|
|
|
993
988
|
Parameters
|
|
@@ -1001,11 +996,11 @@ class InteractiveViewer:
|
|
|
1001
996
|
--------
|
|
1002
997
|
>>> viewer.add_boolean('show_grid', value=True)
|
|
1003
998
|
>>> viewer.update_boolean('show_grid', value=False)
|
|
1004
|
-
>>> viewer.
|
|
999
|
+
>>> viewer.state['show_grid']
|
|
1005
1000
|
False
|
|
1006
1001
|
"""
|
|
1007
1002
|
updates = {}
|
|
1008
|
-
if value
|
|
1003
|
+
if not value == _NO_UPDATE:
|
|
1009
1004
|
updates["value"] = value
|
|
1010
1005
|
if updates:
|
|
1011
1006
|
self.parameters[name].update(updates)
|
|
@@ -1021,7 +1016,7 @@ class InteractiveViewer:
|
|
|
1021
1016
|
"""
|
|
1022
1017
|
Update a selection parameter's value and/or options.
|
|
1023
1018
|
|
|
1024
|
-
Updates a parameter created by :meth:`~syd.
|
|
1019
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_selection`.
|
|
1025
1020
|
See :class:`~syd.parameters.SelectionParameter` for details about value validation.
|
|
1026
1021
|
|
|
1027
1022
|
Parameters
|
|
@@ -1045,9 +1040,9 @@ class InteractiveViewer:
|
|
|
1045
1040
|
... value='purple')
|
|
1046
1041
|
"""
|
|
1047
1042
|
updates = {}
|
|
1048
|
-
if value
|
|
1043
|
+
if not value == _NO_UPDATE:
|
|
1049
1044
|
updates["value"] = value
|
|
1050
|
-
if options
|
|
1045
|
+
if not options == _NO_UPDATE:
|
|
1051
1046
|
updates["options"] = options
|
|
1052
1047
|
if updates:
|
|
1053
1048
|
self.parameters[name].update(updates)
|
|
@@ -1063,7 +1058,7 @@ class InteractiveViewer:
|
|
|
1063
1058
|
"""
|
|
1064
1059
|
Update a multiple selection parameter's values and/or options.
|
|
1065
1060
|
|
|
1066
|
-
Updates a parameter created by :meth:`~syd.
|
|
1061
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_multiple_selection`.
|
|
1067
1062
|
See :class:`~syd.parameters.MultipleSelectionParameter` for details about value validation.
|
|
1068
1063
|
|
|
1069
1064
|
Parameters
|
|
@@ -1089,9 +1084,9 @@ class InteractiveViewer:
|
|
|
1089
1084
|
... value=['cheese', 'bacon'])
|
|
1090
1085
|
"""
|
|
1091
1086
|
updates = {}
|
|
1092
|
-
if value
|
|
1087
|
+
if not value == _NO_UPDATE:
|
|
1093
1088
|
updates["value"] = value
|
|
1094
|
-
if options
|
|
1089
|
+
if not options == _NO_UPDATE:
|
|
1095
1090
|
updates["options"] = options
|
|
1096
1091
|
if updates:
|
|
1097
1092
|
self.parameters[name].update(updates)
|
|
@@ -1108,7 +1103,7 @@ class InteractiveViewer:
|
|
|
1108
1103
|
"""
|
|
1109
1104
|
Update an integer parameter's value and/or bounds.
|
|
1110
1105
|
|
|
1111
|
-
Updates a parameter created by :meth:`~syd.
|
|
1106
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_integer`.
|
|
1112
1107
|
See :class:`~syd.parameters.IntegerParameter` for details about value validation.
|
|
1113
1108
|
|
|
1114
1109
|
Parameters
|
|
@@ -1131,11 +1126,11 @@ class InteractiveViewer:
|
|
|
1131
1126
|
>>> viewer.update_integer('count', min_value=7, max_value=15)
|
|
1132
1127
|
"""
|
|
1133
1128
|
updates = {}
|
|
1134
|
-
if value
|
|
1129
|
+
if not value == _NO_UPDATE:
|
|
1135
1130
|
updates["value"] = value
|
|
1136
|
-
if min_value
|
|
1131
|
+
if not min_value == _NO_UPDATE:
|
|
1137
1132
|
updates["min_value"] = min_value
|
|
1138
|
-
if max_value
|
|
1133
|
+
if not max_value == _NO_UPDATE:
|
|
1139
1134
|
updates["max_value"] = max_value
|
|
1140
1135
|
if updates:
|
|
1141
1136
|
self.parameters[name].update(updates)
|
|
@@ -1153,7 +1148,7 @@ class InteractiveViewer:
|
|
|
1153
1148
|
"""
|
|
1154
1149
|
Update a float parameter's value, bounds, and/or step size.
|
|
1155
1150
|
|
|
1156
|
-
Updates a parameter created by :meth:`~syd.
|
|
1151
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_float`.
|
|
1157
1152
|
See :class:`~syd.parameters.FloatParameter` for details about value validation.
|
|
1158
1153
|
|
|
1159
1154
|
Parameters
|
|
@@ -1180,13 +1175,13 @@ class InteractiveViewer:
|
|
|
1180
1175
|
... min_value=15.0, max_value=30.0, step=0.1)
|
|
1181
1176
|
"""
|
|
1182
1177
|
updates = {}
|
|
1183
|
-
if value
|
|
1178
|
+
if not value == _NO_UPDATE:
|
|
1184
1179
|
updates["value"] = value
|
|
1185
|
-
if min_value
|
|
1180
|
+
if not min_value == _NO_UPDATE:
|
|
1186
1181
|
updates["min_value"] = min_value
|
|
1187
|
-
if max_value
|
|
1182
|
+
if not max_value == _NO_UPDATE:
|
|
1188
1183
|
updates["max_value"] = max_value
|
|
1189
|
-
if step
|
|
1184
|
+
if not step == _NO_UPDATE:
|
|
1190
1185
|
updates["step"] = step
|
|
1191
1186
|
if updates:
|
|
1192
1187
|
self.parameters[name].update(updates)
|
|
@@ -1203,7 +1198,7 @@ class InteractiveViewer:
|
|
|
1203
1198
|
"""
|
|
1204
1199
|
Update an integer range parameter's values and/or bounds.
|
|
1205
1200
|
|
|
1206
|
-
Updates a parameter created by :meth:`~syd.
|
|
1201
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_integer_range`.
|
|
1207
1202
|
See :class:`~syd.parameters.IntegerRangeParameter` for details about value validation.
|
|
1208
1203
|
|
|
1209
1204
|
Parameters
|
|
@@ -1228,11 +1223,11 @@ class InteractiveViewer:
|
|
|
1228
1223
|
>>> viewer.update_integer_range('age_range', min_value=20, max_value=80)
|
|
1229
1224
|
"""
|
|
1230
1225
|
updates = {}
|
|
1231
|
-
if value
|
|
1226
|
+
if not value == _NO_UPDATE:
|
|
1232
1227
|
updates["value"] = value
|
|
1233
|
-
if min_value
|
|
1228
|
+
if not min_value == _NO_UPDATE:
|
|
1234
1229
|
updates["min_value"] = min_value
|
|
1235
|
-
if max_value
|
|
1230
|
+
if not max_value == _NO_UPDATE:
|
|
1236
1231
|
updates["max_value"] = max_value
|
|
1237
1232
|
if updates:
|
|
1238
1233
|
self.parameters[name].update(updates)
|
|
@@ -1250,7 +1245,7 @@ class InteractiveViewer:
|
|
|
1250
1245
|
"""
|
|
1251
1246
|
Update a float range parameter's values, bounds, and/or step size.
|
|
1252
1247
|
|
|
1253
|
-
Updates a parameter created by :meth:`~syd.
|
|
1248
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_float_range`.
|
|
1254
1249
|
See :class:`~syd.parameters.FloatRangeParameter` for details about value validation.
|
|
1255
1250
|
|
|
1256
1251
|
Parameters
|
|
@@ -1278,13 +1273,13 @@ class InteractiveViewer:
|
|
|
1278
1273
|
... min_value=5.0, max_value=50.0, step=0.1)
|
|
1279
1274
|
"""
|
|
1280
1275
|
updates = {}
|
|
1281
|
-
if value
|
|
1276
|
+
if not value == _NO_UPDATE:
|
|
1282
1277
|
updates["value"] = value
|
|
1283
|
-
if min_value
|
|
1278
|
+
if not min_value == _NO_UPDATE:
|
|
1284
1279
|
updates["min_value"] = min_value
|
|
1285
|
-
if max_value
|
|
1280
|
+
if not max_value == _NO_UPDATE:
|
|
1286
1281
|
updates["max_value"] = max_value
|
|
1287
|
-
if step
|
|
1282
|
+
if not step == _NO_UPDATE:
|
|
1288
1283
|
updates["step"] = step
|
|
1289
1284
|
if updates:
|
|
1290
1285
|
self.parameters[name].update(updates)
|
|
@@ -1295,13 +1290,11 @@ class InteractiveViewer:
|
|
|
1295
1290
|
name: str,
|
|
1296
1291
|
*,
|
|
1297
1292
|
value: Union[int, _NoUpdate] = _NO_UPDATE,
|
|
1298
|
-
min_value: Union[Optional[int], _NoUpdate] = _NO_UPDATE,
|
|
1299
|
-
max_value: Union[Optional[int], _NoUpdate] = _NO_UPDATE,
|
|
1300
1293
|
) -> None:
|
|
1301
1294
|
"""
|
|
1302
1295
|
Update an unbounded integer parameter's value and/or bounds.
|
|
1303
1296
|
|
|
1304
|
-
Updates a parameter created by :meth:`~syd.
|
|
1297
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_unbounded_integer`.
|
|
1305
1298
|
See :class:`~syd.parameters.UnboundedIntegerParameter` for details about value validation.
|
|
1306
1299
|
|
|
1307
1300
|
Parameters
|
|
@@ -1309,31 +1302,17 @@ class InteractiveViewer:
|
|
|
1309
1302
|
name : str
|
|
1310
1303
|
Name of the unbounded integer parameter to update
|
|
1311
1304
|
value : int, optional
|
|
1312
|
-
New value (
|
|
1313
|
-
min_value : int or None, optional
|
|
1314
|
-
New minimum value, or None for no minimum (if not provided, no change)
|
|
1315
|
-
max_value : int or None, optional
|
|
1316
|
-
New maximum value, or None for no maximum (if not provided, no change)
|
|
1305
|
+
New value (if not provided, no change)
|
|
1317
1306
|
|
|
1318
1307
|
Examples
|
|
1319
1308
|
--------
|
|
1320
|
-
>>> viewer.add_unbounded_integer('population',
|
|
1321
|
-
... value=1000000,
|
|
1322
|
-
... min_value=0) # No maximum
|
|
1309
|
+
>>> viewer.add_unbounded_integer('population', value=1000000)
|
|
1323
1310
|
>>> # Update just the value
|
|
1324
1311
|
>>> viewer.update_unbounded_integer('population', value=2000000)
|
|
1325
|
-
>>> # Add a maximum bound (current value will be clamped if needed)
|
|
1326
|
-
>>> viewer.update_unbounded_integer('population', max_value=1500000)
|
|
1327
|
-
>>> # Remove the minimum bound
|
|
1328
|
-
>>> viewer.update_unbounded_integer('population', min_value=None)
|
|
1329
1312
|
"""
|
|
1330
1313
|
updates = {}
|
|
1331
|
-
if value
|
|
1314
|
+
if not value == _NO_UPDATE:
|
|
1332
1315
|
updates["value"] = value
|
|
1333
|
-
if min_value is not _NO_UPDATE:
|
|
1334
|
-
updates["min_value"] = min_value
|
|
1335
|
-
if max_value is not _NO_UPDATE:
|
|
1336
|
-
updates["max_value"] = max_value
|
|
1337
1316
|
if updates:
|
|
1338
1317
|
self.parameters[name].update(updates)
|
|
1339
1318
|
|
|
@@ -1343,14 +1322,12 @@ class InteractiveViewer:
|
|
|
1343
1322
|
name: str,
|
|
1344
1323
|
*,
|
|
1345
1324
|
value: Union[float, _NoUpdate] = _NO_UPDATE,
|
|
1346
|
-
min_value: Union[Optional[float], _NoUpdate] = _NO_UPDATE,
|
|
1347
|
-
max_value: Union[Optional[float], _NoUpdate] = _NO_UPDATE,
|
|
1348
1325
|
step: Union[Optional[float], _NoUpdate] = _NO_UPDATE,
|
|
1349
1326
|
) -> None:
|
|
1350
1327
|
"""
|
|
1351
1328
|
Update an unbounded float parameter's value, bounds, and/or step size.
|
|
1352
1329
|
|
|
1353
|
-
Updates a parameter created by :meth:`~syd.
|
|
1330
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_unbounded_float`.
|
|
1354
1331
|
See :class:`~syd.parameters.UnboundedFloatParameter` for details about value validation.
|
|
1355
1332
|
|
|
1356
1333
|
Parameters
|
|
@@ -1359,36 +1336,23 @@ class InteractiveViewer:
|
|
|
1359
1336
|
Name of the unbounded float parameter to update
|
|
1360
1337
|
value : float, optional
|
|
1361
1338
|
New value (will be rounded if step is set) (if not provided, no change)
|
|
1362
|
-
min_value : float or None, optional
|
|
1363
|
-
New minimum value, or None for no minimum (if not provided, no change)
|
|
1364
|
-
max_value : float or None, optional
|
|
1365
|
-
New maximum value, or None for no maximum (if not provided, no change)
|
|
1366
1339
|
step : float or None, optional
|
|
1367
1340
|
New step size for rounding, or None for no rounding (if not provided, no change)
|
|
1368
1341
|
|
|
1369
1342
|
Examples
|
|
1370
1343
|
--------
|
|
1371
|
-
>>> viewer.add_unbounded_float('wavelength',
|
|
1372
|
-
... value=550e-9, # Nanometers
|
|
1373
|
-
... min_value=0.0,
|
|
1374
|
-
... step=1e-9)
|
|
1344
|
+
>>> viewer.add_unbounded_float('wavelength', value=550e-9, step=1e-9)
|
|
1375
1345
|
>>> # Update value (will be rounded if step is set)
|
|
1376
|
-
>>> viewer.update_unbounded_float('wavelength', value=632.8e-9)
|
|
1377
|
-
>>> # Change step size
|
|
1378
|
-
>>> viewer.update_unbounded_float('wavelength',
|
|
1379
|
-
... step=0.1e-9, # Finer control
|
|
1380
|
-
... max_value=1000e-9) # Infrared limit
|
|
1346
|
+
>>> viewer.update_unbounded_float('wavelength', value=632.8e-9)
|
|
1347
|
+
>>> # Change step size
|
|
1348
|
+
>>> viewer.update_unbounded_float('wavelength', step=0.1e-9)
|
|
1381
1349
|
>>> # Remove step size (allow any precision)
|
|
1382
1350
|
>>> viewer.update_unbounded_float('wavelength', step=None)
|
|
1383
1351
|
"""
|
|
1384
1352
|
updates = {}
|
|
1385
|
-
if value
|
|
1353
|
+
if not value == _NO_UPDATE:
|
|
1386
1354
|
updates["value"] = value
|
|
1387
|
-
if
|
|
1388
|
-
updates["min_value"] = min_value
|
|
1389
|
-
if max_value is not _NO_UPDATE:
|
|
1390
|
-
updates["max_value"] = max_value
|
|
1391
|
-
if step is not _NO_UPDATE:
|
|
1355
|
+
if not step == _NO_UPDATE:
|
|
1392
1356
|
updates["step"] = step
|
|
1393
1357
|
if updates:
|
|
1394
1358
|
self.parameters[name].update(updates)
|
|
@@ -1404,7 +1368,7 @@ class InteractiveViewer:
|
|
|
1404
1368
|
"""
|
|
1405
1369
|
Update a button parameter's label and/or callback function.
|
|
1406
1370
|
|
|
1407
|
-
Updates a parameter created by :meth:`~syd.
|
|
1371
|
+
Updates a parameter created by :meth:`~syd.viewer.Viewer.add_button`.
|
|
1408
1372
|
See :class:`~syd.parameters.ButtonAction` for details.
|
|
1409
1373
|
|
|
1410
1374
|
Parameters
|
|
@@ -1418,16 +1382,16 @@ class InteractiveViewer:
|
|
|
1418
1382
|
|
|
1419
1383
|
Examples
|
|
1420
1384
|
--------
|
|
1421
|
-
>>> def new_callback():
|
|
1385
|
+
>>> def new_callback(state):
|
|
1422
1386
|
... print("New action...")
|
|
1423
1387
|
>>> viewer.update_button('reset',
|
|
1424
|
-
... label='
|
|
1388
|
+
... label='New Action!',
|
|
1425
1389
|
... callback=new_callback)
|
|
1426
1390
|
"""
|
|
1427
1391
|
updates = {}
|
|
1428
|
-
if label
|
|
1392
|
+
if not label == _NO_UPDATE:
|
|
1429
1393
|
updates["label"] = label
|
|
1430
|
-
if callback
|
|
1394
|
+
if not callback == _NO_UPDATE:
|
|
1431
1395
|
callback = self._prepare_function(
|
|
1432
1396
|
callback,
|
|
1433
1397
|
context="Updating button callback:",
|