22Classes for the ticks and x- and y-axis.
33"""
44
5+ import contextlib
56import datetime
67import functools
78import logging
@@ -536,6 +537,26 @@ def formatter(self, formatter):
536537 self ._formatter = formatter
537538
538539
540+ @contextlib .contextmanager
541+ def _rc_context_raw (snapshot ):
542+ """
543+ Like ``mpl.rc_context(snapshot)`` but bypasses ``RcParams`` validators
544+ on entry and exit; re-applying a snapshot to its own values must not
545+ re-trigger one-shot validator warnings (e.g. ``toolbar='toolmanager'``).
546+ ``snapshot=None`` is a no-op.
547+ """
548+ if snapshot is None :
549+ yield
550+ return
551+ rc = mpl .rcParams
552+ orig = dict (rc )
553+ rc ._update_raw (snapshot )
554+ try :
555+ yield
556+ finally :
557+ rc ._update_raw (orig )
558+
559+
539560class _LazyTickList :
540561 """
541562 A descriptor for lazy instantiation of tick lists.
@@ -553,31 +574,18 @@ def __get__(self, instance, owner):
553574 return self
554575 # instance._get_tick() can itself try to access the majorTicks
555576 # attribute (e.g. in certain projection classes which override
556- # e.g. get_xaxis_text1_transform). In order to avoid infinite
557- # recursion, first set the majorTicks on the instance temporarily
558- # to an empty list. Then create the tick; note that _get_tick()
559- # may call reset_ticks(). Therefore, the final tick list is
560- # created and assigned afterwards .
577+ # e.g. get_xaxis_text1_transform). To avoid infinite recursion,
578+ # bind the attribute to an empty list before calling _get_tick().
579+ # _get_tick() may also call reset_ticks(), which pops the attribute
580+ # from the instance dict; the final setattr below re-binds the
581+ # (now non-empty) list so subsequent accesses skip the descriptor .
561582 attr = 'majorTicks' if self ._major else 'minorTicks'
562- setattr (instance , attr , [])
583+ tick_list = []
584+ setattr (instance , attr , tick_list )
563585 # Build the Tick (and its sub-artists) under the rcParams captured
564586 # at the last Axis.clear() so that a lazily-materialized Tick
565587 # matches an eager (pre-lazy) Tick (see Axis._tick_rcParams).
566- # We avoid rc_context() here because it re-applies rcParams via
567- # RcParams.__setitem__, whose validators emit warnings on every
568- # assignment for keys like toolbar='toolmanager' -- re-setting
569- # the snapshot to its own (identical) values would spuriously
570- # re-trigger those warnings. _update_raw() bypasses the validators
571- # on both entry and exit.
572- if instance ._tick_rcParams is not None :
573- rc = mpl .rcParams
574- orig = dict (rc )
575- rc ._update_raw (instance ._tick_rcParams )
576- try :
577- tick = instance ._get_tick (major = self ._major )
578- finally :
579- rc ._update_raw (orig )
580- else :
588+ with _rc_context_raw (instance ._tick_rcParams ):
581589 tick = instance ._get_tick (major = self ._major )
582590 # Re-apply any set_tick_params() overrides to the fresh Tick.
583591 # Subclasses of Axis (e.g. the SkewXAxis in the skewt gallery
@@ -591,8 +599,9 @@ def __get__(self, instance, owner):
591599 if tick_kw :
592600 tick ._apply_params (** tick_kw )
593601 instance ._propagate_axis_state_to_tick (tick )
594- setattr (instance , attr , [tick ])
595- return getattr (instance , attr )
602+ tick_list .append (tick )
603+ setattr (instance , attr , tick_list )
604+ return tick_list
596605
597606
598607class Axis (martist .Artist ):
0 commit comments