Skip to content

Commit 573f953

Browse files
authored
Add "overwrite" kwarg to all update* figure methods. (#1726)
When True, update operations will overwrite the prior version of all properties. When False (the default), updates are applied recursively and prior properties are retained if not updated.
1 parent 3690e4a commit 573f953

File tree

9 files changed

+336
-47
lines changed

9 files changed

+336
-47
lines changed

Diff for: packages/python/plotly/codegen/figure.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ def update_{plural_name}(
313313
self,
314314
patch=None,
315315
selector=None,
316+
overwrite=False,
316317
row=None, col=None{secondary_y_1},
317318
**kwargs):
318319
\"\"\"
@@ -330,6 +331,10 @@ def update_{plural_name}(
330331
properties corresponding to all of the dictionary's keys, with
331332
values that exactly match the supplied values. If None
332333
(the default), all {singular_name} objects are selected.
334+
overwrite: bool
335+
If True, overwrite existing properties. If False, apply updates
336+
to existing properties recursively, preserving existing
337+
properties that are not specified in the update operation.
333338
row, col: int or None (default None)
334339
Subplot row and column index of {singular_name} objects to select.
335340
To select {singular_name} objects by row and column, the Figure
@@ -348,7 +353,7 @@ def update_{plural_name}(
348353
\"\"\"
349354
for obj in self.select_{plural_name}(
350355
selector=selector, row=row, col=col{secondary_y_2}):
351-
obj.update(patch, **kwargs)
356+
obj.update(patch, overwrite=overwrite, **kwargs)
352357
353358
return self"""
354359
)

Diff for: packages/python/plotly/plotly/basedatatypes.py

+44-14
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ def _ipython_display_(self):
438438
else:
439439
print (repr(self))
440440

441-
def update(self, dict1=None, **kwargs):
441+
def update(self, dict1=None, overwrite=False, **kwargs):
442442
"""
443443
Update the properties of the figure with a dict and/or with
444444
keyword arguments.
@@ -450,6 +450,10 @@ def update(self, dict1=None, **kwargs):
450450
----------
451451
dict1 : dict
452452
Dictionary of properties to be updated
453+
overwrite: bool
454+
If True, overwrite existing properties. If False, apply updates
455+
to existing properties recursively, preserving existing
456+
properties that are not specified in the update operation.
453457
kwargs :
454458
Keyword/value pair of properties to be updated
455459
@@ -484,10 +488,11 @@ def update(self, dict1=None, **kwargs):
484488
if d:
485489
for k, v in d.items():
486490
update_target = self[k]
487-
if update_target == ():
488-
# existing data or frames property is empty
489-
# In this case we accept the v as is.
491+
if update_target == () or overwrite:
490492
if k == "data":
493+
# Overwrite all traces as special due to
494+
# restrictions on trace assignment
495+
self.data = ()
491496
self.add_traces(v)
492497
else:
493498
# Accept v
@@ -843,7 +848,14 @@ def for_each_trace(self, fn, selector=None, row=None, col=None, secondary_y=None
843848
return self
844849

845850
def update_traces(
846-
self, patch=None, selector=None, row=None, col=None, secondary_y=None, **kwargs
851+
self,
852+
patch=None,
853+
selector=None,
854+
row=None,
855+
col=None,
856+
secondary_y=None,
857+
overwrite=False,
858+
**kwargs
847859
):
848860
"""
849861
Perform a property update operation on all traces that satisfy the
@@ -877,6 +889,10 @@ def update_traces(
877889
created using plotly.subplots.make_subplots. See the docstring
878890
for the specs argument to make_subplots for more info on
879891
creating subplots with secondary y-axes.
892+
overwrite: bool
893+
If True, overwrite existing properties. If False, apply updates
894+
to existing properties recursively, preserving existing
895+
properties that are not specified in the update operation.
880896
**kwargs
881897
Additional property updates to apply to each selected trace. If
882898
a property is specified in both patch and in **kwargs then the
@@ -890,10 +906,10 @@ def update_traces(
890906
for trace in self.select_traces(
891907
selector=selector, row=row, col=col, secondary_y=secondary_y
892908
):
893-
trace.update(patch, **kwargs)
909+
trace.update(patch, overwrite=overwrite, **kwargs)
894910
return self
895911

896-
def update_layout(self, dict1=None, **kwargs):
912+
def update_layout(self, dict1=None, overwrite=False, **kwargs):
897913
"""
898914
Update the properties of the figure's layout with a dict and/or with
899915
keyword arguments.
@@ -905,6 +921,10 @@ def update_layout(self, dict1=None, **kwargs):
905921
----------
906922
dict1 : dict
907923
Dictionary of properties to be updated
924+
overwrite: bool
925+
If True, overwrite existing properties. If False, apply updates
926+
to existing properties recursively, preserving existing
927+
properties that are not specified in the update operation.
908928
kwargs :
909929
Keyword/value pair of properties to be updated
910930
@@ -913,7 +933,7 @@ def update_layout(self, dict1=None, **kwargs):
913933
BaseFigure
914934
The Figure object that the update_layout method was called on
915935
"""
916-
self.layout.update(dict1, **kwargs)
936+
self.layout.update(dict1, overwrite=overwrite, **kwargs)
917937
return self
918938

919939
def _select_layout_subplots_by_prefix(
@@ -2697,7 +2717,7 @@ def _is_dict_list(v):
26972717
return isinstance(v, list) and len(v) > 0 and isinstance(v[0], dict)
26982718

26992719
@staticmethod
2700-
def _perform_update(plotly_obj, update_obj):
2720+
def _perform_update(plotly_obj, update_obj, overwrite=False):
27012721
"""
27022722
Helper to support the update() methods on :class:`BaseFigure` and
27032723
:class:`BasePlotlyType`
@@ -2747,6 +2767,12 @@ def _perform_update(plotly_obj, update_obj):
27472767
# ------------------------
27482768
for key in update_obj:
27492769
val = update_obj[key]
2770+
2771+
if overwrite:
2772+
# Don't recurse and assign property as-is
2773+
plotly_obj[key] = val
2774+
continue
2775+
27502776
validator = plotly_obj._get_prop_validator(key)
27512777

27522778
if isinstance(validator, CompoundValidator) and isinstance(val, dict):
@@ -3530,7 +3556,7 @@ def _raise_on_invalid_property_error(self, *args):
35303556
)
35313557
)
35323558

3533-
def update(self, dict1=None, **kwargs):
3559+
def update(self, dict1=None, overwrite=False, **kwargs):
35343560
"""
35353561
Update the properties of an object with a dict and/or with
35363562
keyword arguments.
@@ -3542,6 +3568,10 @@ def update(self, dict1=None, **kwargs):
35423568
----------
35433569
dict1 : dict
35443570
Dictionary of properties to be updated
3571+
overwrite: bool
3572+
If True, overwrite existing properties. If False, apply updates
3573+
to existing properties recursively, preserving existing
3574+
properties that are not specified in the update operation.
35453575
kwargs :
35463576
Keyword/value pair of properties to be updated
35473577
@@ -3552,11 +3582,11 @@ def update(self, dict1=None, **kwargs):
35523582
"""
35533583
if self.figure:
35543584
with self.figure.batch_update():
3555-
BaseFigure._perform_update(self, dict1)
3556-
BaseFigure._perform_update(self, kwargs)
3585+
BaseFigure._perform_update(self, dict1, overwrite=overwrite)
3586+
BaseFigure._perform_update(self, kwargs, overwrite=overwrite)
35573587
else:
3558-
BaseFigure._perform_update(self, dict1)
3559-
BaseFigure._perform_update(self, kwargs)
3588+
BaseFigure._perform_update(self, dict1, overwrite=overwrite)
3589+
BaseFigure._perform_update(self, kwargs, overwrite=overwrite)
35603590

35613591
return self
35623592

0 commit comments

Comments
 (0)