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

Skip to content

Lazier ticks for large speedup when creating large arrays of axes. #16067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions lib/matplotlib/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,21 @@ def __get__(self, instance, cls):
if self._major:
instance.majorTicks = []
tick = instance._get_tick(major=True)
try:
tick.set_clip_path(instance.axes.patch)
except AttributeError:
pass
tick._apply_params(**instance._major_tick_kw)
instance.majorTicks.append(tick)
return instance.majorTicks
else:
instance.minorTicks = []
tick = instance._get_tick(major=False)
try:
tick.set_clip_path(instance.axes.patch)
except AttributeError:
pass
tick._apply_params(**instance._minor_tick_kw)
instance.minorTicks.append(tick)
return instance.minorTicks

Expand Down Expand Up @@ -719,6 +729,12 @@ def __init__(self, axes, pickradius=15):
majorTicks = _LazyTickList(major=True)
minorTicks = _LazyTickList(major=False)

def _lazy_get_ticks_or_empty(self, *, major=True):
# Return ticks without triggering auto-instantiation. This is
# important for performance!
name = "majorTicks" if major else "minorTicks"
return vars(self).get(name, [])

def get_remove_overlapping_locs(self):
return self._remove_overlapping_locs

Expand Down Expand Up @@ -838,11 +854,11 @@ def set_tick_params(self, which='major', reset=False, **kw):
else:
if which in ['major', 'both']:
self._major_tick_kw.update(kwtrans)
for tick in self.majorTicks:
for tick in self._lazy_get_ticks_or_empty(major=True):
tick._apply_params(**kwtrans)
if which in ['minor', 'both']:
self._minor_tick_kw.update(kwtrans)
for tick in self.minorTicks:
for tick in self._lazy_get_ticks_or_empty(major=False):
tick._apply_params(**kwtrans)
# special-case label color to also apply to the offset text
if 'labelcolor' in kwtrans:
Expand Down Expand Up @@ -897,7 +913,8 @@ def _translate_tick_kw(kw):

def set_clip_path(self, clippath, transform=None):
martist.Artist.set_clip_path(self, clippath, transform)
for child in self.majorTicks + self.minorTicks:
for child in (self._lazy_get_ticks_or_empty(major=True)
+ self._lazy_get_ticks_or_empty(major=False)):
child.set_clip_path(clippath, transform)
self.stale = True

Expand Down
10 changes: 10 additions & 0 deletions lib/matplotlib/spines.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,16 @@ def _adjust_location(self):

@allow_rasterization
def draw(self, renderer):
# The calls to get_x/yaxis_transform are necessary to set up the spine
# transforms properly in the case of rectilinear axes. (This was
# previously done implicitly on tick init, but now ticks are init'ed
# lazily at draw time.) Really, one just needs to call
# _ensure_position_is_set(), except that this breaks polar axes which
# are brittle.
self.axes.get_xaxis_transform('tick1')
self.axes.get_xaxis_transform('tick2')
self.axes.get_yaxis_transform('tick1')
self.axes.get_yaxis_transform('tick2')
self._adjust_location()
ret = super().draw(renderer)
self.stale = False
Expand Down