Skip to content

Commit e23076f

Browse files
authored
Template specification fixes (#1819)
* Allow pio.template[] to lookup flaglist of templates, fixes #1807 * Fix fig.update to update layout with string
1 parent 240d0b4 commit e23076f

File tree

3 files changed

+46
-19
lines changed

3 files changed

+46
-19
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,10 @@ def update(self, dict1=None, overwrite=False, **kwargs):
497497
else:
498498
# Accept v
499499
self[k] = v
500-
elif isinstance(update_target, BasePlotlyType) or (
500+
elif (
501+
isinstance(update_target, BasePlotlyType)
502+
and isinstance(v, (dict, BasePlotlyType))
503+
) or (
501504
isinstance(update_target, tuple)
502505
and isinstance(update_target[0], BasePlotlyType)
503506
):

Diff for: packages/python/plotly/plotly/io/_templates.py

+30-18
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import json
99
from functools import reduce
1010

11+
from six import string_types
12+
1113
try:
1214
from math import gcd
1315
except ImportError:
@@ -61,24 +63,34 @@ def __iter__(self):
6163
return iter(self._templates)
6264

6365
def __getitem__(self, item):
64-
template = self._templates[item]
65-
if template is Lazy:
66-
from plotly.graph_objs.layout import Template
67-
68-
if item == "none":
69-
# "none" is a special built-in named template that applied no defaults
70-
template = Template()
71-
self._templates[item] = template
72-
else:
73-
# Load template from package data
74-
path = os.path.join("package_data", "templates", item + ".json")
75-
template_str = pkgutil.get_data("plotly", path).decode("utf-8")
76-
template_dict = json.loads(template_str)
77-
template = Template(template_dict)
78-
79-
self._templates[item] = template
80-
81-
return template
66+
if isinstance(item, string_types):
67+
template_names = item.split("+")
68+
else:
69+
template_names = [item]
70+
71+
templates = []
72+
for template_name in template_names:
73+
template = self._templates[template_name]
74+
if template is Lazy:
75+
from plotly.graph_objs.layout import Template
76+
77+
if template_name == "none":
78+
# "none" is a special built-in named template that applied no defaults
79+
template = Template()
80+
self._templates[template_name] = template
81+
else:
82+
# Load template from package data
83+
path = os.path.join(
84+
"package_data", "templates", template_name + ".json"
85+
)
86+
template_str = pkgutil.get_data("plotly", path).decode("utf-8")
87+
template_dict = json.loads(template_str)
88+
template = Template(template_dict)
89+
90+
self._templates[template_name] = template
91+
templates.append(self._templates[template_name])
92+
93+
return self.merge_templates(*templates)
8294

8395
def __setitem__(self, key, value):
8496
self._templates[key] = self._validate(value)

Diff for: packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_template.py

+12
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,18 @@ def test_merge_by_flaglist_string(self):
508508
self.assertEqual(self.template1, self.template1_orig)
509509
self.assertEqual(self.template2, self.template2_orig)
510510

511+
def test_flaglist_string_getitem(self):
512+
result = pio.templates["template1+template2"]
513+
expected = self.expected1_2
514+
self.assertEqual(result, expected)
515+
516+
def test_update_template_with_flaglist(self):
517+
fig = go.Figure()
518+
fig.update(layout_template="template1+template2")
519+
result = fig.layout.template
520+
expected = self.expected1_2
521+
self.assertEqual(result, expected)
522+
511523
def test_set_default_template(self):
512524
orig_default = pio.templates.default
513525
pio.templates.default = "plotly"

0 commit comments

Comments
 (0)