Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 70b25df

Browse filesBrowse files
committed
Cleanup text.py.
- Use Bbox attributes more. - Early-exit Annotation._update_position_xypixel if arrowprops is None to dedent most of the function. Save many repeated calls to Text.get_window_extent(self, renderer) in that function.
1 parent a6c3c22 commit 70b25df
Copy full SHA for 70b25df

File tree

Expand file treeCollapse file tree

1 file changed

+76
-103
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+76
-103
lines changed

‎lib/matplotlib/text.py

Copy file name to clipboardExpand all lines: lib/matplotlib/text.py
+76-103Lines changed: 76 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,11 @@ def contains(self, mouseevent):
205205
# Explicitly use Text.get_window_extent(self) and not
206206
# self.get_window_extent() so that Annotation.contains does not
207207
# accidentally cover the entire annotation bounding box.
208-
l, b, w, h = Text.get_window_extent(self).bounds
209-
r, t = l + w, b + h
208+
bbox = Text.get_window_extent(self)
209+
inside = (bbox.x0 <= mouseevent.x <= bbox.x1
210+
and bbox.y0 <= mouseevent.y <= bbox.y1)
210211

211-
x, y = mouseevent.x, mouseevent.y
212-
inside = (l <= x <= r and b <= y <= t)
213212
cattr = {}
214-
215213
# if the text has a surrounding patch, also check containment for it,
216214
# and merge the results with the results for the text.
217215
if self._bbox_patch:
@@ -1312,13 +1310,14 @@ def __call__(self, renderer):
13121310
"""
13131311
if isinstance(self._artist, Artist):
13141312
bbox = self._artist.get_window_extent(renderer)
1315-
l, b, w, h = bbox.bounds
13161313
xf, yf = self._ref_coord
1317-
x, y = l + w * xf, b + h * yf
1314+
x = bbox.x0 + bbox.width * xf
1315+
y = bbox.y0 + bbox.height * yf
13181316
elif isinstance(self._artist, BboxBase):
1319-
l, b, w, h = self._artist.bounds
1317+
bbox = self._artist
13201318
xf, yf = self._ref_coord
1321-
x, y = l + w * xf, b + h * yf
1319+
x = bbox.x0 + bbox.width * xf
1320+
y = bbox.y0 + bbox.height * yf
13221321
elif isinstance(self._artist, Transform):
13231322
x, y = self._artist.transform(self._ref_coord)
13241323
else:
@@ -1407,7 +1406,7 @@ def _get_xy_transform(self, renderer, s):
14071406
# bbox0 = self._get_bbox(renderer, bbox)
14081407

14091408
if bbox0 is not None:
1410-
xy0 = bbox0.bounds[:2]
1409+
xy0 = bbox0.p0
14111410
elif bbox_name == "offset":
14121411
xy0 = self._get_ref_xy(renderer)
14131412

@@ -1426,7 +1425,7 @@ def _get_xy_transform(self, renderer, s):
14261425
dpp = fontsize * self.figure.get_dpi() / 72.
14271426
tr = Affine2D().scale(dpp)
14281427
elif unit == "fraction":
1429-
w, h = bbox0.bounds[2:]
1428+
w, h = bbox0.size
14301429
tr = Affine2D().scale(w, h)
14311430
else:
14321431
raise ValueError("%s is not a recognized coordinate" % s)
@@ -1823,99 +1822,73 @@ def _update_position_xytext(self, renderer, xy_pixel):
18231822
# generate transformation,
18241823
self.set_transform(self._get_xy_transform(renderer, self.anncoords))
18251824

1826-
ox0, oy0 = self._get_xy_display()
1827-
ox1, oy1 = xy_pixel
1828-
1829-
if self.arrowprops is not None:
1830-
x0, y0 = xy_pixel
1831-
l, b, w, h = Text.get_window_extent(self, renderer).bounds
1832-
r = l + w
1833-
t = b + h
1834-
xc = 0.5 * (l + r)
1835-
yc = 0.5 * (b + t)
1836-
1837-
d = self.arrowprops.copy()
1838-
ms = d.pop("mutation_scale", self.get_size())
1839-
self.arrow_patch.set_mutation_scale(ms)
1840-
1841-
if "arrowstyle" not in d:
1842-
# Approximately simulate the YAArrow.
1843-
# Pop its kwargs:
1844-
shrink = d.pop('shrink', 0.0)
1845-
width = d.pop('width', 4)
1846-
headwidth = d.pop('headwidth', 12)
1847-
# Ignore frac--it is useless.
1848-
frac = d.pop('frac', None)
1849-
if frac is not None:
1850-
cbook._warn_external(
1851-
"'frac' option in 'arrowprops' is no longer supported;"
1852-
" use 'headlength' to set the head length in points.")
1853-
headlength = d.pop('headlength', 12)
1854-
1855-
# NB: ms is in pts
1856-
stylekw = dict(head_length=headlength / ms,
1857-
head_width=headwidth / ms,
1858-
tail_width=width / ms)
1859-
1860-
self.arrow_patch.set_arrowstyle('simple', **stylekw)
1861-
1862-
# using YAArrow style:
1863-
# pick the (x, y) corner of the text bbox closest to point
1864-
# annotated
1865-
xpos = ((l, 0), (xc, 0.5), (r, 1))
1866-
ypos = ((b, 0), (yc, 0.5), (t, 1))
1867-
1868-
_, (x, relposx) = min((abs(val[0] - x0), val) for val in xpos)
1869-
_, (y, relposy) = min((abs(val[0] - y0), val) for val in ypos)
1870-
1871-
self._arrow_relpos = (relposx, relposy)
1872-
1873-
r = np.hypot((y - y0), (x - x0))
1874-
shrink_pts = shrink * r / renderer.points_to_pixels(1)
1875-
self.arrow_patch.shrinkA = shrink_pts
1876-
self.arrow_patch.shrinkB = shrink_pts
1877-
1878-
# adjust the starting point of the arrow relative to
1879-
# the textbox.
1880-
# TODO : Rotation needs to be accounted.
1881-
relpos = self._arrow_relpos
1882-
bbox = Text.get_window_extent(self, renderer)
1883-
ox0 = bbox.x0 + bbox.width * relpos[0]
1884-
oy0 = bbox.y0 + bbox.height * relpos[1]
1885-
1886-
# The arrow will be drawn from (ox0, oy0) to (ox1,
1887-
# oy1). It will be first clipped by patchA and patchB.
1888-
# Then it will be shrunk by shrinkA and shrinkB
1889-
# (in points). If patch A is not set, self.bbox_patch
1890-
# is used.
1891-
1892-
self.arrow_patch.set_positions((ox0, oy0), (ox1, oy1))
1893-
1894-
if "patchA" in d:
1895-
self.arrow_patch.set_patchA(d.pop("patchA"))
1825+
if self.arrowprops is None:
1826+
return
1827+
1828+
x1, y1 = xy_pixel # Annotated position.
1829+
bbox = Text.get_window_extent(self, renderer)
1830+
1831+
d = self.arrowprops.copy()
1832+
ms = d.pop("mutation_scale", self.get_size())
1833+
self.arrow_patch.set_mutation_scale(ms)
1834+
1835+
if "arrowstyle" not in d:
1836+
# Approximately simulate the YAArrow.
1837+
# Pop its kwargs:
1838+
shrink = d.pop('shrink', 0.0)
1839+
width = d.pop('width', 4)
1840+
headwidth = d.pop('headwidth', 12)
1841+
# Ignore frac--it is useless.
1842+
frac = d.pop('frac', None)
1843+
if frac is not None:
1844+
cbook._warn_external(
1845+
"'frac' option in 'arrowprops' is no longer supported;"
1846+
" use 'headlength' to set the head length in points.")
1847+
headlength = d.pop('headlength', 12)
1848+
1849+
# NB: ms is in pts
1850+
stylekw = dict(head_length=headlength / ms,
1851+
head_width=headwidth / ms,
1852+
tail_width=width / ms)
1853+
1854+
self.arrow_patch.set_arrowstyle('simple', **stylekw)
1855+
1856+
# using YAArrow style:
1857+
# pick the corner of the text bbox closest to annotated point.
1858+
xpos = [(bbox.x0, 0), ((bbox.x0 + bbox.x1) / 2, 0.5), (bbox.x1, 1)]
1859+
ypos = [(bbox.y0, 0), ((bbox.y0 + bbox.y1) / 2, 0.5), (bbox.y1, 1)]
1860+
x, relposx = min(xpos, key=lambda v: abs(v[0] - x1))
1861+
y, relposy = min(ypos, key=lambda v: abs(v[0] - y1))
1862+
self._arrow_relpos = (relposx, relposy)
1863+
r = np.hypot(y - y1, x - x1)
1864+
shrink_pts = shrink * r / renderer.points_to_pixels(1)
1865+
self.arrow_patch.shrinkA = self.arrow_patch.shrinkB = shrink_pts
1866+
1867+
# adjust the starting point of the arrow relative to the textbox.
1868+
# TODO : Rotation needs to be accounted.
1869+
relposx, relposy = self._arrow_relpos
1870+
x0 = bbox.x0 + bbox.width * relposx
1871+
y0 = bbox.y0 + bbox.height * relposy
1872+
1873+
# The arrow will be drawn from (x0, y0) to (x1, y1). It will be first
1874+
# clipped by patchA and patchB. Then it will be shrunk by shrinkA and
1875+
# shrinkB (in points). If patch A is not set, self.bbox_patch is used.
1876+
self.arrow_patch.set_positions((x0, y0), (x1, y1))
1877+
1878+
if "patchA" in d:
1879+
self.arrow_patch.set_patchA(d.pop("patchA"))
1880+
else:
1881+
if self._bbox_patch:
1882+
self.arrow_patch.set_patchA(self._bbox_patch)
18961883
else:
1897-
if self._bbox_patch:
1898-
self.arrow_patch.set_patchA(self._bbox_patch)
1899-
else:
1900-
pad = renderer.points_to_pixels(4)
1901-
if self.get_text() == "":
1902-
self.arrow_patch.set_patchA(None)
1903-
return
1904-
1905-
bbox = Text.get_window_extent(self, renderer)
1906-
l, b, w, h = bbox.bounds
1907-
l -= pad / 2.
1908-
b -= pad / 2.
1909-
w += pad
1910-
h += pad
1911-
r = Rectangle(xy=(l, b),
1912-
width=w,
1913-
height=h,
1914-
)
1915-
r.set_transform(IdentityTransform())
1916-
r.set_clip_on(False)
1917-
1918-
self.arrow_patch.set_patchA(r)
1884+
if self.get_text() == "":
1885+
self.arrow_patch.set_patchA(None)
1886+
return
1887+
pad = renderer.points_to_pixels(4)
1888+
r = Rectangle(xy=(bbox.x0 - pad / 2, bbox.y0 - pad / 2),
1889+
width=bbox.width + pad, height=bbox.height + pad,
1890+
transform=IdentityTransform(), clip_on=False)
1891+
self.arrow_patch.set_patchA(r)
19191892

19201893
@artist.allow_rasterization
19211894
def draw(self, renderer):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.