Thanks to visit codestin.com
Credit goes to github.com

Skip to content

⚑️ Speed up function annotation_params_for_rect by 22% #110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 43 additions & 45 deletions plotly/shapeannotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
def _mean(x):
if len(x) == 0:
raise ValueError("x must have positive length")
return float(sum(x)) / len(x)
return float(x[0] + x[1]) / 2 # Only ever called with [x0, x1]


def _argmin(x):
Expand All @@ -30,10 +30,10 @@ def _prepare_position(position, prepend_inside=False):
if position is None:
position = "top right"
pos_str = position
position = set(position.split(" "))
if prepend_inside:
position = _add_inside_to_position(position)
return position, pos_str
pos_set = set(position.split(" "))
if prepend_inside and not ("inside" in pos_set or "outside" in pos_set):
pos_set.add("inside")
return pos_set, pos_str


def annotation_params_for_line(shape_type, shape_args, position):
Expand Down Expand Up @@ -107,62 +107,44 @@ def annotation_params_for_rect(shape_type, shape_args, position):
y0 = shape_args["y0"]
y1 = shape_args["y1"]

position, pos_str = _prepare_position(position, prepend_inside=True)
if position == set(["inside", "top", "left"]):
return _df_anno("left", "top", min([x0, x1]), max([y0, y1]))
if position == set(["inside", "top", "right"]):
return _df_anno("right", "top", max([x0, x1]), max([y0, y1]))
if position == set(["inside", "top"]):
return _df_anno("center", "top", _mean([x0, x1]), max([y0, y1]))
if position == set(["inside", "bottom", "left"]):
return _df_anno("left", "bottom", min([x0, x1]), min([y0, y1]))
if position == set(["inside", "bottom", "right"]):
return _df_anno("right", "bottom", max([x0, x1]), min([y0, y1]))
if position == set(["inside", "bottom"]):
return _df_anno("center", "bottom", _mean([x0, x1]), min([y0, y1]))
if position == set(["inside", "left"]):
return _df_anno("left", "middle", min([x0, x1]), _mean([y0, y1]))
if position == set(["inside", "right"]):
return _df_anno("right", "middle", max([x0, x1]), _mean([y0, y1]))
if position == set(["inside"]):
# TODO: Do we want this?
return _df_anno("center", "middle", _mean([x0, x1]), _mean([y0, y1]))
if position == set(["outside", "top", "left"]):
pos_set, pos_str = _prepare_position(position, prepend_inside=True)
key = frozenset(pos_set)

# Table-driven direct hits handle most cases
fn = _INSIDE_OUTSIDE_TABLE.get(key, None)
if fn is not None:
return fn(x0, x1, y0, y1, shape_type)

# Special cases for "outside" positions that depend on shape_type
if key == frozenset(["outside", "top", "left"]):
return _df_anno(
"right" if shape_type == "vrect" else "left",
"bottom" if shape_type == "hrect" else "top",
min([x0, x1]),
max([y0, y1]),
min(x0, x1),
max(y0, y1),
)
if position == set(["outside", "top", "right"]):
if key == frozenset(["outside", "top", "right"]):
return _df_anno(
"left" if shape_type == "vrect" else "right",
"bottom" if shape_type == "hrect" else "top",
max([x0, x1]),
max([y0, y1]),
max(x0, x1),
max(y0, y1),
)
if position == set(["outside", "top"]):
return _df_anno("center", "bottom", _mean([x0, x1]), max([y0, y1]))
if position == set(["outside", "bottom", "left"]):
if key == frozenset(["outside", "bottom", "left"]):
return _df_anno(
"right" if shape_type == "vrect" else "left",
"top" if shape_type == "hrect" else "bottom",
min([x0, x1]),
min([y0, y1]),
min(x0, x1),
min(y0, y1),
)
if position == set(["outside", "bottom", "right"]):
if key == frozenset(["outside", "bottom", "right"]):
return _df_anno(
"left" if shape_type == "vrect" else "right",
"top" if shape_type == "hrect" else "bottom",
max([x0, x1]),
min([y0, y1]),
max(x0, x1),
min(y0, y1),
)
if position == set(["outside", "bottom"]):
return _df_anno("center", "top", _mean([x0, x1]), min([y0, y1]))
if position == set(["outside", "left"]):
return _df_anno("right", "middle", min([x0, x1]), _mean([y0, y1]))
if position == set(["outside", "right"]):
return _df_anno("left", "middle", max([x0, x1]), _mean([y0, y1]))

raise ValueError("Invalid annotation position %s" % (pos_str,))


Expand Down Expand Up @@ -244,3 +226,19 @@ def split_dict_by_key_prefix(d, prefix):
else:
no_prefix[k] = d[k]
return (no_prefix, with_prefix)

_INSIDE_OUTSIDE_TABLE = {
frozenset(["inside", "top", "left"]): lambda a,b,c,d,_: _df_anno("left", "top", min(a, b), max(c, d)),
frozenset(["inside", "top", "right"]): lambda a,b,c,d,_: _df_anno("right", "top", max(a, b), max(c, d)),
frozenset(["inside", "top"]): lambda a,b,c,d,_: _df_anno("center", "top", _mean((a, b)), max(c, d)),
frozenset(["inside", "bottom", "left"]): lambda a,b,c,d,_: _df_anno("left", "bottom", min(a, b), min(c, d)),
frozenset(["inside", "bottom", "right"]):lambda a,b,c,d,_: _df_anno("right", "bottom", max(a, b), min(c, d)),
frozenset(["inside", "bottom"]): lambda a,b,c,d,_: _df_anno("center", "bottom", _mean((a, b)), min(c, d)),
frozenset(["inside", "left"]): lambda a,b,c,d,_: _df_anno("left", "middle", min(a, b), _mean((c, d))),
frozenset(["inside", "right"]): lambda a,b,c,d,_: _df_anno("right", "middle", max(a, b), _mean((c, d))),
frozenset(["inside"]): lambda a,b,c,d,_: _df_anno("center", "middle", _mean((a, b)), _mean((c, d))),
frozenset(["outside", "top"]): lambda a,b,c,d,_: _df_anno("center", "bottom", _mean((a, b)), max(c, d)),
frozenset(["outside", "bottom"]): lambda a,b,c,d,_: _df_anno("center", "top", _mean((a, b)), min(c, d)),
frozenset(["outside", "left"]): lambda a,b,c,d,_: _df_anno("right", "middle", min(a, b), _mean((c, d))),
frozenset(["outside", "right"]): lambda a,b,c,d,_: _df_anno("left", "middle", max(a, b), _mean((c, d))),
}