diff --git a/lib/matplotlib/cbook.py b/lib/matplotlib/cbook.py index 87656b5c3c00..0c49c70b37fa 100644 --- a/lib/matplotlib/cbook.py +++ b/lib/matplotlib/cbook.py @@ -286,7 +286,7 @@ def process(self, s, *args, **kwargs): """ if self._signals is not None: _api.check_in_list(self._signals, signal=s) - for cid, ref in list(self.callbacks.get(s, {}).items()): + for ref in list(self.callbacks.get(s, {}).values()): func = ref() if func is not None: try: @@ -1634,6 +1634,10 @@ def _safe_first_finite(obj, *, skip_nonfinite=True): def safe_isfinite(val): if val is None: return False + try: + return math.isfinite(val) + except TypeError: + pass try: return np.isfinite(val) if np.isscalar(val) else True except TypeError: @@ -1661,7 +1665,10 @@ def safe_isfinite(val): raise RuntimeError("matplotlib does not " "support generators as input") else: - return next((val for val in obj if safe_isfinite(val)), safe_first_element(obj)) + for val in obj: + if safe_isfinite(val): + return val + return safe_first_element(obj) def sanitize_sequence(data): diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py index 434bb5423543..f36e19a1d17a 100644 --- a/lib/matplotlib/colors.py +++ b/lib/matplotlib/colors.py @@ -210,10 +210,12 @@ def _sanitize_extrema(ex): ret = float(ex) return ret +_nth_color_re = re.compile(r"\AC[0-9]+\Z") + def _is_nth_color(c): """Return whether *c* can be interpreted as an item in the color cycle.""" - return isinstance(c, str) and re.match(r"\AC[0-9]+\Z", c) + return isinstance(c, str) and _nth_color_re.match(c) def is_color_like(c): diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index f2ffa09932de..7e39807e4c71 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -189,13 +189,14 @@ def set_children(self, *children): # Parents are stored as weak references, so that if the # parents are destroyed, references from the children won't # keep them alive. + id_self = id(self) for child in children: # Use weak references so this dictionary won't keep obsolete nodes # alive; the callback deletes the dictionary entry. This is a # performance improvement over using WeakValueDictionary. ref = weakref.ref( - self, lambda _, pop=child._parents.pop, k=id(self): pop(k)) - child._parents[id(self)] = ref + self, lambda _, pop=child._parents.pop, k=id_self: pop(k)) + child._parents[id_self] = ref def frozen(self): """ @@ -670,6 +671,8 @@ def intersection(bbox1, bbox2): y1 = np.minimum(bbox1.ymax, bbox2.ymax) return Bbox([[x0, y0], [x1, y1]]) if x0 <= x1 and y0 <= y1 else None +_default_minpos = np.array([np.inf, np.inf]) + class Bbox(BboxBase): """ @@ -765,7 +768,7 @@ def __init__(self, points, **kwargs): raise ValueError('Bbox points must be of the form ' '"[[x0, y0], [x1, y1]]".') self._points = points - self._minpos = np.array([np.inf, np.inf]) + self._minpos = _default_minpos.copy() self._ignore = True # it is helpful in some contexts to know if the bbox is a # default or has been mutated; we store the orig points to @@ -1773,7 +1776,7 @@ def __array__(self, *args, **kwargs): def __eq__(self, other): if getattr(other, "is_affine", False) and hasattr(other, "get_matrix"): - return np.all(self.get_matrix() == other.get_matrix()) + return (self.get_matrix() == other.get_matrix()).all() return NotImplemented def transform(self, values):