From c93596500e912d00cf8db547c1d48df8875a8c6f Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 23 Jan 2018 03:07:25 -0800 Subject: [PATCH] Alternate implementation of lazy ticks. Speeds up creation of 10x10 subplots ~4-fold (from 2.7s to 0.7s). --- lib/matplotlib/axis.py | 46 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 338c2ad5b1d2..19b752f19208 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -662,6 +662,29 @@ class Ticker(object): formatter = None +class _LazyTickList(object): + """ + A descriptor for lazy instantiation of tick lists. + + See comment above definition of the ``majorTicks`` and ``minorTicks`` + attributes. + """ + + def __init__(self, major): + self._major = major + + def __get__(self, instance, cls): + if instance is None: + return self + else: + if self._major: + instance.majorTicks = [instance._get_tick(major=True)] + return instance.majorTicks + else: + instance.minorTicks = [instance._get_tick(major=False)] + return instance.minorTicks + + class Axis(artist.Artist): """ Public attributes @@ -696,8 +719,6 @@ def __init__(self, axes, pickradius=15): self.label = self._get_label() self.labelpad = rcParams['axes.labelpad'] self.offsetText = self._get_offset_text() - self.majorTicks = [] - self.minorTicks = [] self.unit_data = None self.pickradius = pickradius @@ -708,6 +729,12 @@ def __init__(self, axes, pickradius=15): self.cla() self._set_scale('linear') + # During initialization, Axis objects often create ticks that are later + # unused; this turns out to be a very slow step. Instead, use a custom + # descriptor to make the tick lists lazy and instantiate them as needed. + majorTicks = _LazyTickList(major=True) + minorTicks = _LazyTickList(major=False) + def set_label_coords(self, x, y, transform=None): """ Set the coordinates of the label. By default, the x @@ -798,12 +825,15 @@ def reset_ticks(self): Each list starts with a single fresh Tick. """ - del self.majorTicks[:] - del self.minorTicks[:] - - self.majorTicks.extend([self._get_tick(major=True)]) - self.minorTicks.extend([self._get_tick(major=False)]) - + # Restore the lazy tick lists. + try: + del self.majorTicks + except AttributeError: + pass + try: + del self.minorTicks + except AttributeError: + pass try: self.set_clip_path(self.axes.patch) except AttributeError: