Skip to content

Commit 8a62ba7

Browse files
Skeleton of annotated shapes test
Moved the tests for axis spanning shapes and their annotated versions to test_autoshapes.
1 parent 9d90f39 commit 8a62ba7

File tree

3 files changed

+603
-13
lines changed

3 files changed

+603
-13
lines changed

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

+30-13
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ def annotation_params_for_line(shape_type, shape_args, position):
2525
M = "middle"
2626
aY = max(Y)
2727
iY = min(Y)
28-
mY = mean(Y)
28+
eY = mean(Y)
2929
aaY = argmax(Y)
3030
aiY = argmin(Y)
3131
aX = max(X)
3232
iX = min(X)
33-
mX = mean(X)
33+
eX = mean(X)
3434
aaX = argmax(X)
3535
aiX = argmin(X)
3636

@@ -58,13 +58,13 @@ def annotation_params_for_line(shape_type, shape_args, position):
5858
if position == "top right":
5959
return _df_anno(R, B, aX, Y[aaX])
6060
if position == "top":
61-
return _df_anno(C, B, mX, mY)
61+
return _df_anno(C, B, eX, eY)
6262
if position == "bottom left":
6363
return _df_anno(L, T, iX, Y[aiX])
6464
if position == "bottom right":
6565
return _df_anno(R, T, aX, Y[aaX])
6666
if position == "bottom":
67-
return _df_anno(C, T, mX, mY)
67+
return _df_anno(C, T, eX, eY)
6868
if position == "left":
6969
return _df_anno(R, M, iX, Y[aiX])
7070
if position == "right":
@@ -98,15 +98,35 @@ def annotation_params_for_rect(shape_type, shape_args, position):
9898
# TODO: Do we want this?
9999
return _df_anno("center", "middle", mean([x0, x1]), mean([y0, y1]))
100100
if position == "outside top left":
101-
return _df_anno("right", "bottom", min([x0, x1]), max([y0, y1]))
101+
return _df_anno(
102+
"right" if shape_type == "vrect" else "left",
103+
"bottom" if shape_type == "hrect" else "top",
104+
min([x0, x1]),
105+
max([y0, y1]),
106+
)
102107
if position == "outside top right":
103-
return _df_anno("left", "bottom", max([x0, x1]), max([y0, y1]))
108+
return _df_anno(
109+
"left" if shape_type == "vrect" else "right",
110+
"bottom" if shape_type == "hrect" else "top",
111+
max([x0, x1]),
112+
max([y0, y1]),
113+
)
104114
if position == "outside top":
105115
return _df_anno("center", "bottom", mean([x0, x1]), max([y0, y1]))
106116
if position == "outside bottom left":
107-
return _df_anno("right", "top", min([x0, x1]), min([y0, y1]))
117+
return _df_anno(
118+
"right" if shape_type == "vrect" else "left",
119+
"top" if shape_type == "hrect" else "bottom",
120+
min([x0, x1]),
121+
min([y0, y1]),
122+
)
108123
if position == "outside bottom right":
109-
return _df_anno("left", "top", max([x0, x1]), min([y0, y1]))
124+
return _df_anno(
125+
"left" if shape_type == "vrect" else "right",
126+
"top" if shape_type == "hrect" else "bottom",
127+
max([x0, x1]),
128+
min([y0, y1]),
129+
)
110130
if position == "outside bottom":
111131
return _df_anno("center", "top", mean([x0, x1]), min([y0, y1]))
112132
if position == "outside left":
@@ -141,11 +161,8 @@ def axis_spanning_shape_annotation(annotation, shape_type, shape_args, kwargs):
141161
annotation_position, annotation_ prefixed kwargs or the original annotation
142162
passed in to this function.
143163
"""
144-
# Force to go.layout.Annotation, no matter if it is that already, a dict or None
145-
# TODO: We can't import go.layout.Annotation so we initialize this as a
146-
# dict. This strategy is inferior to initializing as a go.layout.Annotation
147-
# because there's no checking if a key is valid. Eventually it'd be better
148-
# to use go.layout.Annotation.
164+
# TODO: Would it be better if annotation were initialized to an instace of
165+
# go.layout.Annotation ?
149166
if annotation is None:
150167
annotation = dict()
151168
# set properties based on annotation_ prefixed kwargs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import plotly.graph_objects as go
2+
from plotly.subplots import make_subplots
3+
from itertools import product
4+
import os
5+
6+
visualize = os.environ.get("VISUALIZE", 0)
7+
8+
line_positions = [
9+
"top left",
10+
"top right",
11+
"top",
12+
"bottom left",
13+
"bottom right",
14+
"bottom",
15+
"left",
16+
"right",
17+
]
18+
rect_positions = [
19+
"inside top left",
20+
"inside top right",
21+
"inside top",
22+
"inside bottom left",
23+
"inside bottom right",
24+
"inside bottom",
25+
"inside left",
26+
"inside right",
27+
"inside",
28+
"outside top left",
29+
"outside top right",
30+
"outside top",
31+
"outside bottom left",
32+
"outside bottom right",
33+
"outside bottom",
34+
"outside left",
35+
"outside right",
36+
]
37+
fig = make_subplots(
38+
2, 2, column_widths=[3, 1], row_heights=[1, 3], vertical_spacing=0.07
39+
)
40+
for rc, pos, ax, sh in zip(
41+
product(range(2), range(2)),
42+
[line_positions, line_positions, rect_positions, rect_positions],
43+
["x", "y", "x", "y"],
44+
["vline", "hline", "vrect", "hrect"],
45+
):
46+
r, c = rc
47+
r += 1
48+
c = ((c + 1) % 2 if r == 1 else c) + 1
49+
fig.update_xaxes(row=r, col=c, range=[0, len(pos) if sh[0] == "v" else 1])
50+
fig.update_yaxes(row=r, col=c, range=[0, len(pos) if sh[0] == "h" else 1])
51+
fig.add_trace(go.Scatter(x=[], y=[]), row=r, col=c)
52+
for n, p in enumerate(pos):
53+
f = eval("fig.add_%s" % (sh,))
54+
args = (
55+
{ax: n + 0.5}
56+
if sh.endswith("line")
57+
else {ax + "0": n + 0.1, ax + "1": n + 0.9}
58+
)
59+
args["annotation_text"] = p
60+
args["annotation_position"] = p
61+
args["annotation_font_size"] = 8
62+
args["annotation_font_color"] = "white"
63+
args["row"] = r
64+
args["col"] = c
65+
args["annotation_bgcolor"] = "grey"
66+
if sh[0] == "v":
67+
args["annotation_textangle"] = 90
68+
f(**args)
69+
fig.update_layout(title="Annotated hline, vline, hrect, vrect")
70+
71+
if visualize:
72+
fig.show()

0 commit comments

Comments
 (0)