diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index acde4fb179a2..23a27316b532 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -5,6 +5,7 @@ import functools import logging import math +import numbers from numbers import Real import weakref @@ -1862,6 +1863,7 @@ def transform(renderer) -> Transform xy, xycoords=xycoords, annotation_clip=annotation_clip) + self.xytext = xytext # warn about wonky input data if (xytext is None and textcoords is not None and @@ -2027,7 +2029,12 @@ def draw(self, renderer): # docstring inherited if renderer is not None: self._renderer = renderer - if not self.get_visible() or not self._check_xy(renderer): + + visible = self.get_visible() and self._check_xy(renderer) + + self._check_xytext() + + if not visible: return # Update text positions before `Text.draw` would, so that the # FancyArrowPatch is correctly positioned. @@ -2046,7 +2053,11 @@ def get_window_extent(self, renderer=None): # docstring inherited # This block is the same as in Text.get_window_extent, but we need to # set the renderer before calling update_positions(). - if not self.get_visible() or not self._check_xy(renderer): + visible = self.get_visible() and self._check_xy(renderer) + + self._check_xytext() + + if not visible: return Bbox.unit() if renderer is not None: self._renderer = renderer @@ -2072,4 +2083,29 @@ def get_tightbbox(self, renderer=None): return super().get_tightbbox(renderer) + def _check_xytext(self, renderer=None): + """Check whether the annotation text at *xy_pixel* should be drawn.""" + valid = True + + if self.xytext is None: + return valid + + try: + # transforming the coordinates + coords = np.array(self.get_transform().transform(self.xytext)) + if all(isinstance(xyt, numbers.Number) for xyt in coords): + valid = not np.isnan(coords).any() and np.isfinite(coords).all() + except TypeError: + # If transformation fails, check raw coordinates + if all(isinstance(xyt, numbers.Number) for xyt in self.xytext): + is_numerical = not np.isnan(self.xytext).any() + finite = np.isfinite(self.xytext).all() + valid = is_numerical and finite + else: + # For non-number coordinates (like units), assume valid + valid = True + + if not valid: + raise ValueError("xytext coordinates must be finite numbers") + return valid _docstring.interpd.register(Annotation=Annotation.__init__.__doc__)
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: