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

Skip to content

Commit 8138d84

Browse files
committed
Annotation cleanups.
- Make error messages more consistent. - Remove commonted-out handling of xycoords="bbox"; the functionality of specifiying coordinates relative to a bbox is already provided by passing a callable that ignores its input and returns that bbox. - Make _get_xy take xy as a single argument instead of two; merge the equivalent _get_ref_xy and _get_position_xy. In offsetbox, no need to specifically handle self.boxcoords being a tuple: _get_xy already handles that case. Also rename the last parameter of _get_xy to the more meaningful "coords".
1 parent 3e98838 commit 8138d84

File tree

4 files changed

+42
-75
lines changed

4 files changed

+42
-75
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Invalid types for Annotation xycoords now raise TypeError
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Previously, a `RuntimeError` would be raised in some cases.

lib/matplotlib/offsetbox.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,19 +1400,9 @@ def get_tightbbox(self, renderer=None):
14001400
for child in self.get_children()])
14011401

14021402
def update_positions(self, renderer):
1403-
"""
1404-
Update pixel positions for the annotated point, the text and the arrow.
1405-
"""
1406-
1407-
x, y = self.xybox
1408-
if isinstance(self.boxcoords, tuple):
1409-
xcoord, ycoord = self.boxcoords
1410-
x1, y1 = self._get_xy(renderer, x, y, xcoord)
1411-
x2, y2 = self._get_xy(renderer, x, y, ycoord)
1412-
ox0, oy0 = x1, y2
1413-
else:
1414-
ox0, oy0 = self._get_xy(renderer, x, y, self.boxcoords)
1403+
"""Update pixel positions for the annotated point, the text, and the arrow."""
14151404

1405+
ox0, oy0 = self._get_xy(renderer, self.xybox, self.boxcoords)
14161406
bbox = self.offsetbox.get_bbox(renderer)
14171407
fw, fh = self._box_alignment
14181408
self.offsetbox.set_offset(

lib/matplotlib/tests/test_text.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,8 @@ def test_annotation_contains():
248248

249249

250250
@pytest.mark.parametrize('err, xycoords, match', (
251-
(RuntimeError, print, "Unexpected return type from callable"),
252-
(RuntimeError, [0, 0], r"Unexpected type for 'xycoords'"),
251+
(TypeError, print, "xycoords callable must return a BboxBase or Transform, not a"),
252+
(TypeError, [0, 0], r"'xycoords' must be an instance of str, tuple"),
253253
(ValueError, "foo", "'foo' is not a valid coordinate"),
254254
(ValueError, "foo bar", "'foo bar' is not a valid coordinate"),
255255
(ValueError, "offset foo", "xycoords cannot be an offset coordinate"),

lib/matplotlib/text.py

Lines changed: 35 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,59 +1431,56 @@ def __init__(self,
14311431

14321432
self._draggable = None
14331433

1434-
def _get_xy(self, renderer, x, y, s):
1435-
if isinstance(s, tuple):
1436-
s1, s2 = s
1437-
else:
1438-
s1, s2 = s, s
1439-
if s1 == 'data':
1434+
def _get_xy(self, renderer, xy, coords):
1435+
x, y = xy
1436+
xcoord, ycoord = coords if isinstance(coords, tuple) else (coords, coords)
1437+
if xcoord == 'data':
14401438
x = float(self.convert_xunits(x))
1441-
if s2 == 'data':
1439+
if ycoord == 'data':
14421440
y = float(self.convert_yunits(y))
1443-
return self._get_xy_transform(renderer, s).transform((x, y))
1441+
return self._get_xy_transform(renderer, coords).transform((x, y))
14441442

1445-
def _get_xy_transform(self, renderer, s):
1443+
def _get_xy_transform(self, renderer, coords):
14461444

1447-
if isinstance(s, tuple):
1448-
s1, s2 = s
1445+
if isinstance(coords, tuple):
1446+
xcoord, ycoord = coords
14491447
from matplotlib.transforms import blended_transform_factory
1450-
tr1 = self._get_xy_transform(renderer, s1)
1451-
tr2 = self._get_xy_transform(renderer, s2)
1452-
tr = blended_transform_factory(tr1, tr2)
1453-
return tr
1454-
elif callable(s):
1455-
tr = s(renderer)
1448+
tr1 = self._get_xy_transform(renderer, xcoord)
1449+
tr2 = self._get_xy_transform(renderer, ycoord)
1450+
return blended_transform_factory(tr1, tr2)
1451+
elif callable(coords):
1452+
tr = coords(renderer)
14561453
if isinstance(tr, BboxBase):
14571454
return BboxTransformTo(tr)
14581455
elif isinstance(tr, Transform):
14591456
return tr
14601457
else:
1461-
raise RuntimeError(
1462-
f"Unexpected return type from callable: "
1463-
f"expected BboxBase or Transform, but got {type(tr).__name__}.")
1464-
elif isinstance(s, Artist):
1465-
bbox = s.get_window_extent(renderer)
1458+
raise TypeError(
1459+
f"xycoords callable must return a BboxBase or Transform, not a "
1460+
f"{type(tr).__name__}")
1461+
elif isinstance(coords, Artist):
1462+
bbox = coords.get_window_extent(renderer)
14661463
return BboxTransformTo(bbox)
1467-
elif isinstance(s, BboxBase):
1468-
return BboxTransformTo(s)
1469-
elif isinstance(s, Transform):
1470-
return s
1471-
elif not isinstance(s, str):
1472-
raise RuntimeError(
1473-
f"Unexpected type for 'xycoords'. This must be one of str, (str, str), "
1474-
f"Artist, Transform, or callable, but got {type(s).__name__}.")
1475-
1476-
if s == 'data':
1464+
elif isinstance(coords, BboxBase):
1465+
return BboxTransformTo(coords)
1466+
elif isinstance(coords, Transform):
1467+
return coords
1468+
elif not isinstance(coords, str):
1469+
raise TypeError(
1470+
f"'xycoords' must be an instance of str, tuple[str, str], Artist, "
1471+
f"Transform, or Callable, not a {type(coords).__name__}")
1472+
1473+
if coords == 'data':
14771474
return self.axes.transData
1478-
elif s == 'polar':
1475+
elif coords == 'polar':
14791476
from matplotlib.projections import PolarAxes
14801477
tr = PolarAxes.PolarTransform()
14811478
trans = tr + self.axes.transData
14821479
return trans
14831480

1484-
s_ = s.split()
1481+
s_ = coords.split()
14851482
if len(s_) != 2:
1486-
raise ValueError(f"{s!r} is not a valid coordinate")
1483+
raise ValueError(f"{coords!r} is not a valid coordinate")
14871484

14881485
bbox0, xy0 = None, None
14891486

@@ -1495,16 +1492,11 @@ def _get_xy_transform(self, renderer, s):
14951492
bbox0 = self.figure.bbox
14961493
elif bbox_name == "axes":
14971494
bbox0 = self.axes.bbox
1498-
# elif bbox_name == "bbox":
1499-
# if bbox is None:
1500-
# raise RuntimeError("bbox is specified as a coordinate but "
1501-
# "never set")
1502-
# bbox0 = self._get_bbox(renderer, bbox)
15031495

15041496
if bbox0 is not None:
15051497
xy0 = bbox0.p0
15061498
elif bbox_name == "offset":
1507-
xy0 = self._get_ref_xy(renderer)
1499+
xy0 = self._get_position_xy(renderer)
15081500

15091501
if xy0 is not None:
15101502
# reference x, y in display coordinate
@@ -1528,24 +1520,7 @@ def _get_xy_transform(self, renderer, s):
15281520
return tr.translate(ref_x, ref_y)
15291521

15301522
else:
1531-
raise ValueError(f"{s!r} is not a valid coordinate")
1532-
1533-
def _get_ref_xy(self, renderer):
1534-
"""
1535-
Return x, y (in display coordinates) that is to be used for a reference
1536-
of any offset coordinate.
1537-
"""
1538-
return self._get_xy(renderer, *self.xy, self.xycoords)
1539-
1540-
# def _get_bbox(self, renderer):
1541-
# if hasattr(bbox, "bounds"):
1542-
# return bbox
1543-
# elif hasattr(bbox, "get_window_extent"):
1544-
# bbox = bbox.get_window_extent()
1545-
# return bbox
1546-
# else:
1547-
# raise ValueError("A bbox instance is expected but got %s" %
1548-
# str(bbox))
1523+
raise ValueError(f"{coords!r} is not a valid coordinate")
15491524

15501525
def set_annotation_clip(self, b):
15511526
"""
@@ -1572,8 +1547,7 @@ def get_annotation_clip(self):
15721547

15731548
def _get_position_xy(self, renderer):
15741549
"""Return the pixel position of the annotated point."""
1575-
x, y = self.xy
1576-
return self._get_xy(renderer, x, y, self.xycoords)
1550+
return self._get_xy(renderer, self.xy, self.xycoords)
15771551

15781552
def _check_xy(self, renderer=None):
15791553
"""Check whether the annotation at *xy_pixel* should be drawn."""

0 commit comments

Comments
 (0)