Skip to content

Commit bea85bf

Browse files
committed
add add/select/update tests for annotations
1 parent 8771488 commit bea85bf

File tree

4 files changed

+169
-46
lines changed

4 files changed

+169
-46
lines changed

packages/python/plotly/codegen/figure.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ def for_each_{singular_name}(
450450
Returns the Figure object that the method was called on
451451
\"\"\"
452452
for obj in self._select_annotations_like(
453-
property='{plural_name}',
453+
prop='{plural_name}',
454454
selector=selector,
455455
row=row,
456456
col=col,
@@ -513,7 +513,7 @@ def update_{plural_name}(
513513
Returns the Figure object that the method was called on
514514
\"\"\"
515515
for obj in self._select_annotations_like(
516-
property='{plural_name}',
516+
prop='{plural_name}',
517517
selector=selector,
518518
row=row,
519519
col=col,

packages/python/plotly/plotly/graph_objs/_figure.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15902,7 +15902,7 @@ def for_each_annotation(
1590215902
Returns the Figure object that the method was called on
1590315903
"""
1590415904
for obj in self._select_annotations_like(
15905-
property="annotations",
15905+
prop="annotations",
1590615906
selector=selector,
1590715907
row=row,
1590815908
col=col,
@@ -15959,7 +15959,7 @@ def update_annotations(
1595915959
Returns the Figure object that the method was called on
1596015960
"""
1596115961
for obj in self._select_annotations_like(
15962-
property="annotations",
15962+
prop="annotations",
1596315963
selector=selector,
1596415964
row=row,
1596515965
col=col,
@@ -16403,11 +16403,7 @@ def for_each_image(self, fn, selector=None, row=None, col=None, secondary_y=None
1640316403
Returns the Figure object that the method was called on
1640416404
"""
1640516405
for obj in self._select_annotations_like(
16406-
property="images",
16407-
selector=selector,
16408-
row=row,
16409-
col=col,
16410-
secondary_y=secondary_y,
16406+
prop="images", selector=selector, row=row, col=col, secondary_y=secondary_y
1641116407
):
1641216408
fn(obj)
1641316409

@@ -16460,11 +16456,7 @@ def update_images(
1646016456
Returns the Figure object that the method was called on
1646116457
"""
1646216458
for obj in self._select_annotations_like(
16463-
property="images",
16464-
selector=selector,
16465-
row=row,
16466-
col=col,
16467-
secondary_y=secondary_y,
16459+
prop="images", selector=selector, row=row, col=col, secondary_y=secondary_y
1646816460
):
1646916461
obj.update(patch, **kwargs)
1647016462

@@ -16683,11 +16675,7 @@ def for_each_shape(self, fn, selector=None, row=None, col=None, secondary_y=None
1668316675
Returns the Figure object that the method was called on
1668416676
"""
1668516677
for obj in self._select_annotations_like(
16686-
property="shapes",
16687-
selector=selector,
16688-
row=row,
16689-
col=col,
16690-
secondary_y=secondary_y,
16678+
prop="shapes", selector=selector, row=row, col=col, secondary_y=secondary_y
1669116679
):
1669216680
fn(obj)
1669316681

@@ -16740,11 +16728,7 @@ def update_shapes(
1674016728
Returns the Figure object that the method was called on
1674116729
"""
1674216730
for obj in self._select_annotations_like(
16743-
property="shapes",
16744-
selector=selector,
16745-
row=row,
16746-
col=col,
16747-
secondary_y=secondary_y,
16731+
prop="shapes", selector=selector, row=row, col=col, secondary_y=secondary_y
1674816732
):
1674916733
obj.update(patch, **kwargs)
1675016734

packages/python/plotly/plotly/graph_objs/_figurewidget.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15902,7 +15902,7 @@ def for_each_annotation(
1590215902
Returns the Figure object that the method was called on
1590315903
"""
1590415904
for obj in self._select_annotations_like(
15905-
property="annotations",
15905+
prop="annotations",
1590615906
selector=selector,
1590715907
row=row,
1590815908
col=col,
@@ -15959,7 +15959,7 @@ def update_annotations(
1595915959
Returns the Figure object that the method was called on
1596015960
"""
1596115961
for obj in self._select_annotations_like(
15962-
property="annotations",
15962+
prop="annotations",
1596315963
selector=selector,
1596415964
row=row,
1596515965
col=col,
@@ -16403,11 +16403,7 @@ def for_each_image(self, fn, selector=None, row=None, col=None, secondary_y=None
1640316403
Returns the Figure object that the method was called on
1640416404
"""
1640516405
for obj in self._select_annotations_like(
16406-
property="images",
16407-
selector=selector,
16408-
row=row,
16409-
col=col,
16410-
secondary_y=secondary_y,
16406+
prop="images", selector=selector, row=row, col=col, secondary_y=secondary_y
1641116407
):
1641216408
fn(obj)
1641316409

@@ -16460,11 +16456,7 @@ def update_images(
1646016456
Returns the Figure object that the method was called on
1646116457
"""
1646216458
for obj in self._select_annotations_like(
16463-
property="images",
16464-
selector=selector,
16465-
row=row,
16466-
col=col,
16467-
secondary_y=secondary_y,
16459+
prop="images", selector=selector, row=row, col=col, secondary_y=secondary_y
1646816460
):
1646916461
obj.update(patch, **kwargs)
1647016462

@@ -16683,11 +16675,7 @@ def for_each_shape(self, fn, selector=None, row=None, col=None, secondary_y=None
1668316675
Returns the Figure object that the method was called on
1668416676
"""
1668516677
for obj in self._select_annotations_like(
16686-
property="shapes",
16687-
selector=selector,
16688-
row=row,
16689-
col=col,
16690-
secondary_y=secondary_y,
16678+
prop="shapes", selector=selector, row=row, col=col, secondary_y=secondary_y
1669116679
):
1669216680
fn(obj)
1669316681

@@ -16740,11 +16728,7 @@ def update_shapes(
1674016728
Returns the Figure object that the method was called on
1674116729
"""
1674216730
for obj in self._select_annotations_like(
16743-
property="shapes",
16744-
selector=selector,
16745-
row=row,
16746-
col=col,
16747-
secondary_y=secondary_y,
16731+
prop="shapes", selector=selector, row=row, col=col, secondary_y=secondary_y
1674816732
):
1674916733
obj.update(patch, **kwargs)
1675016734

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
from __future__ import absolute_import
2+
3+
import types
4+
from unittest import TestCase
5+
6+
import plotly.graph_objs as go
7+
from plotly.subplots import make_subplots
8+
9+
10+
class TestSelectForEachUpdateAnnotations(TestCase):
11+
def setUp(self):
12+
self.fig = make_subplots(
13+
rows=2, cols=2, specs=[[{}, {"secondary_y": True}], [{}, {"type": "polar"}]]
14+
)
15+
16+
def assert_selected(
17+
self, prop, inds, selector=None, row=None, col=None, secondary_y=None
18+
):
19+
# ## Test select_*
20+
# Get select_ method
21+
fn = getattr(self.fig, "select_" + prop)
22+
23+
# Perform selection
24+
res = fn(selector=selector, row=row, col=col, secondary_y=secondary_y)
25+
self.assertIsInstance(res, types.GeneratorType)
26+
objs = list(res)
27+
28+
# Check length of selected objects
29+
self.assertEqual(len(objs), len(inds))
30+
31+
# Check individual annotations
32+
for i, obj in zip(inds, objs):
33+
self.assertEqual(self.fig.layout[prop][i], obj)
34+
35+
# ## Test for_each_*
36+
objs = []
37+
fn = getattr(self.fig, "for_each_" + prop[:-1])
38+
fn(
39+
lambda v: objs.append(v),
40+
selector=selector,
41+
row=row,
42+
col=col,
43+
secondary_y=secondary_y,
44+
)
45+
self.assertEqual(len(objs), len(inds))
46+
for i, obj in zip(inds, objs):
47+
self.assertEqual(self.fig.layout[prop][i], obj)
48+
49+
def assert_update(
50+
self, prop, inds, patch, selector=None, row=None, col=None, secondary_y=None
51+
):
52+
# Copy figure and perform update
53+
fig_orig = go.Figure(self.fig)
54+
fig = go.Figure(self.fig)
55+
fn = getattr(fig, "update_" + prop)
56+
fn(patch, selector=selector, row=row, col=col, secondary_y=secondary_y)
57+
58+
# Get original up updated object lis
59+
objs_orig = fig_orig.layout[prop]
60+
objs = fig.layout[prop]
61+
62+
for i, (obj, obj_orig) in enumerate(zip(objs, objs_orig)):
63+
if i in inds:
64+
# Check that object changed from original
65+
self.assertNotEqual(obj, obj_orig)
66+
67+
# Apply update to original and check that they match now
68+
obj_orig.update(patch)
69+
self.assertEqual(obj, obj_orig)
70+
else:
71+
# Check object unchanged
72+
self.assertEqual(obj, obj_orig)
73+
74+
def test_add_annotations(self):
75+
# Paper annotation
76+
self.fig.add_annotation(text="A")
77+
annot = self.fig.layout.annotations[-1]
78+
self.assertEqual(annot.text, "A")
79+
self.assertEqual(annot.xref, "paper")
80+
self.assertEqual(annot.yref, "paper")
81+
82+
# (1, 1) annotation
83+
self.fig.add_annotation(text="B", row=1, col=1)
84+
annot = self.fig.layout.annotations[-1]
85+
self.assertEqual(annot.text, "B")
86+
self.assertEqual(annot.xref, "x")
87+
self.assertEqual(annot.yref, "y")
88+
89+
# (1, 2) annotation, primary y-axis
90+
self.fig.add_annotation(text="C1", row=1, col=2)
91+
annot = self.fig.layout.annotations[-1]
92+
self.assertEqual(annot.text, "C1")
93+
self.assertEqual(annot.xref, "x2")
94+
self.assertEqual(annot.yref, "y2")
95+
96+
# (1, 2) annotation, secondary y-axis
97+
self.fig.add_annotation(text="C2", row=1, col=2, secondary_y=True)
98+
annot = self.fig.layout.annotations[-1]
99+
self.assertEqual(annot.text, "C2")
100+
self.assertEqual(annot.xref, "x2")
101+
self.assertEqual(annot.yref, "y3")
102+
103+
# (2, 1) annotation
104+
self.fig.add_annotation(text="D", row=2, col=1)
105+
annot = self.fig.layout.annotations[-1]
106+
self.assertEqual(annot.text, "D")
107+
self.assertEqual(annot.xref, "x3")
108+
self.assertEqual(annot.yref, "y4")
109+
110+
# Try to add to (2, 2), which not a valid
111+
with self.assertRaisesRegexp(ValueError, "of type polar"):
112+
self.fig.add_annotation(text="D", row=2, col=2)
113+
114+
def test_select_annotations(self):
115+
(
116+
self.fig.add_annotation(text="A1", arrowcolor="red")
117+
.add_annotation(text="A2", arrowcolor="blue")
118+
.add_annotation(text="B", arrowcolor="red", row=1, col=1)
119+
.add_annotation(text="C1", row=1, col=2)
120+
.add_annotation(text="C2", row=1, col=2, secondary_y=True)
121+
.add_annotation(text="D", arrowcolor="blue", row=2, col=1)
122+
)
123+
124+
# Test selections
125+
self.assert_selected("annotations", [0, 1, 2, 3, 4, 5])
126+
self.assert_selected("annotations", [0, 2], selector=dict(arrowcolor="red"))
127+
self.assert_selected("annotations", [2, 3, 4], row=1)
128+
self.assert_selected("annotations", [2], selector=dict(arrowcolor="red"), row=1)
129+
self.assert_selected("annotations", [0, 1], row="paper", col="paper")
130+
self.assert_selected("annotations", [4], secondary_y=True)
131+
132+
def test_update_annotations(self):
133+
(
134+
self.fig.add_annotation(text="A1", arrowcolor="red")
135+
.add_annotation(text="A2", arrowcolor="blue")
136+
.add_annotation(text="B", arrowcolor="red", row=1, col=1)
137+
.add_annotation(text="C1", row=1, col=2)
138+
.add_annotation(text="C2", row=1, col=2, secondary_y=True)
139+
.add_annotation(text="D", arrowcolor="blue", row=2, col=1)
140+
)
141+
142+
self.assert_update(
143+
"annotations", [0, 1, 2, 3, 4, 5], patch=dict(showarrow=False)
144+
)
145+
self.assert_update(
146+
"annotations",
147+
[1, 5],
148+
patch=dict(showarrow=False),
149+
selector=dict(arrowcolor="blue"),
150+
)
151+
self.assert_update("annotations", [2, 3, 4], patch=dict(showarrow=False), row=1)
152+
self.assert_update("annotations", [2, 5], patch=dict(showarrow=False), col=1)
153+
self.assert_update(
154+
"annotations", [4], patch=dict(showarrow=False), secondary_y=True
155+
)

0 commit comments

Comments
 (0)