From 87197156eb299c1f37ac23c16c83ecb000e9872b Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 27 Aug 2022 10:46:15 +0200 Subject: [PATCH] improve matplotlib import time by caching ArtistInspector --- lib/matplotlib/artist.py | 22 +++++++++++++++++----- lib/matplotlib/axis.py | 20 +++++++++++++++++++- lib/matplotlib/text.py | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index 2e104e3d7fe4..1ca1c1d3e37e 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -1,6 +1,6 @@ from collections import namedtuple import contextlib -from functools import wraps +from functools import lru_cache, wraps import inspect from inspect import Signature, Parameter import logging @@ -1494,17 +1494,29 @@ def get_setters(self): continue func = getattr(self.o, name) if (not callable(func) - or len(inspect.signature(func).parameters) < 2 + or self.number_of_parameters(func) < 2 or self.is_alias(func)): continue setters.append(name[4:]) return setters - def is_alias(self, o): - """Return whether method object *o* is an alias for another method.""" - ds = inspect.getdoc(o) + @staticmethod + @lru_cache(maxsize=None) + def number_of_parameters(func): + """Return number of parameters of the callable *func*.""" + return len(inspect.signature(func).parameters) + + @staticmethod + @lru_cache(maxsize=None) + def is_alias(method): + """ + Return whether the object *method* is an alias for another method. + """ + + ds = inspect.getdoc(method) if ds is None: return False + return ds.startswith('Alias for ') def aliased_name(self, s): diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 128714d5f42f..aa7aee3320b8 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -895,8 +895,11 @@ def clear(self): This does not reset tick and tick label visibility. """ + self.label._reset_visual_defaults() + self.offsetText._reset_visual_defaults() + self.labelpad = mpl.rcParams['axes.labelpad'] - self.label.set_text('') # self.set_label_text would change isDefault_ + self._init() self._set_scale('linear') @@ -2193,6 +2196,13 @@ class XAxis(Axis): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._init() + + def _init(self): + """ + Initialize the label and offsetText instance values and + `label_position` / `offset_text_position`. + """ # x in axes coords, y in display coords (to be updated at draw time by # _update_label_positions and _update_offset_text_position). self.label.set( @@ -2202,6 +2212,7 @@ def __init__(self, *args, **kwargs): self.axes.transAxes, mtransforms.IdentityTransform()), ) self.label_position = 'bottom' + self.offsetText.set( x=1, y=0, verticalalignment='top', horizontalalignment='right', @@ -2444,6 +2455,13 @@ class YAxis(Axis): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._init() + + def _init(self): + """ + Initialize the label and offsetText instance values and + `label_position` / `offset_text_position`. + """ # x in display coords, y in axes coords (to be updated at draw time by # _update_label_positions and _update_offset_text_position). self.label.set( diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index 3c998d540c48..356bdb36a8c0 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -164,6 +164,39 @@ def __init__(self, super().__init__() self._x, self._y = x, y self._text = '' + self._reset_visual_defaults( + text=text, + color=color, + fontproperties=fontproperties, + usetex=usetex, + parse_math=parse_math, + wrap=wrap, + verticalalignment=verticalalignment, + horizontalalignment=horizontalalignment, + multialignment=multialignment, + rotation=rotation, + transform_rotates_text=transform_rotates_text, + linespacing=linespacing, + rotation_mode=rotation_mode, + ) + self.update(kwargs) + + def _reset_visual_defaults( + self, + text='', + color=None, + fontproperties=None, + usetex=None, + parse_math=None, + wrap=False, + verticalalignment='baseline', + horizontalalignment='left', + multialignment=None, + rotation=None, + transform_rotates_text=False, + linespacing=None, + rotation_mode=None, + ): self.set_text(text) self.set_color( color if color is not None else mpl.rcParams["text.color"]) @@ -183,7 +216,6 @@ def __init__(self, linespacing = 1.2 # Maybe use rcParam later. self.set_linespacing(linespacing) self.set_rotation_mode(rotation_mode) - self.update(kwargs) def update(self, kwargs): # docstring inherited