@@ -2477,52 +2477,53 @@ def _parse_cycle(
24772477 Whether to simply return the property cycle or apply it. The cycle is
24782478 only applied (and therefore reset) if it differs from the current one.
24792479 """
2480- # Create the property cycler and update it if necessary
2481- # NOTE: Matplotlib Cycler() objects have built-in __eq__ operator
2482- # so really easy to check if the cycler has changed!
2483- if cycle is not None or cycle_kw :
2480+
2481+ # Create/update cycler only if needed
2482+
2483+ if cycle is not None or cycle_kw or not hasattr ( self , "_current_cycler" ) :
24842484 cycle_kw = cycle_kw or {}
2485- if ncycle != 1 : # ignore for column-by-column plotting commands
2486- cycle_kw .setdefault ("N" , ncycle ) # if None then filled in Colormap()
2487- if isinstance (cycle , str ) and cycle .lower () == "none" :
2488- cycle = False
2489- if not cycle :
2490- args = ()
2491- elif cycle is True : # consistency with 'False' ('reactivate' the cycler)
2492- args = (rc ["axes.prop_cycle" ],)
2493- else :
2494- args = (cycle ,)
2495- cycle = constructor .Cycle (* args , ** cycle_kw )
2496- with warnings .catch_warnings (): # hide 'elementwise-comparison failed'
2497- warnings .simplefilter ("ignore" , FutureWarning )
2498- if return_cycle :
2499- pass
2500- elif cycle != self ._active_cycle :
2485+ if ncycle != 1 :
2486+ cycle_kw .setdefault ("N" , ncycle )
2487+ # Convert string or list to Cycle object
2488+ if isinstance (cycle , (str , list )):
2489+ cycle = constructor .Cycle (cycle , ** cycle_kw )
2490+ elif cycle is True :
2491+ cycle = constructor .Cycle (rc ["axes.prop_cycle" ], ** cycle_kw )
2492+ elif cycle is False :
2493+ cycle = None
2494+ elif cycle is not None and not isinstance (cycle , constructor .Cycle ):
2495+ cycle = constructor .Cycle (cycle , ** cycle_kw )
2496+
2497+ if not hasattr (self , "_current_cycler" ):
2498+ self ._current_cycler = cycle
2499+
2500+ # Update the current cycler if it changed
2501+ if cycle != self ._current_cycler :
2502+ self ._current_cycle = cycle
2503+ if not return_cycle and self ._current_cycler != self ._active_cycle :
25012504 self .set_prop_cycle (cycle )
25022505
2503- # Manually extract and apply settings to outgoing keyword arguments
2504- # if native matplotlib function does not include desired properties
2505- cycle_manually = cycle_manually or {}
2506- parser = self ._get_lines # the _process_plot_var_args instance
2507- props = {} # which keys to apply from property cycler
2508- for prop , key in cycle_manually .items ():
2509- if kwargs .get (key , None ) is None and any (
2510- prop in item for item in parser ._cycler_items
2511- ):
2512- props [prop ] = key
2513- if props :
2514- dict_ = parser ._cycler_items [parser ._idx ]
2515- parser ._idx = (parser ._idx + 1 ) % len (parser ._cycler_items )
2516- for prop , key in props .items ():
2517- value = dict_ [prop ]
2518- if key == "c" : # special case: scatter() color must be converted to hex
2519- value = pcolors .to_hex (value )
2520- kwargs [key ] = value
2506+
2507+ # Use existing cycler if none specified
2508+ if cycle is None :
2509+ cycle = self ._current_cycler
2510+
2511+ # Get next set of properties
2512+ if cycle is not None :
2513+ props = cycle .get_next ()
2514+ if cycle_manually :
2515+ mapped_props = {}
2516+ for prop , value in props .items ():
2517+ if mapped_key := cycle_manually .get (prop ):
2518+ mapped_props [mapped_key ] = value
2519+ for prop in props :
2520+ if prop in cycle_manually :
2521+ kwargs .pop (prop , None )
2522+ kwargs .update (mapped_props )
25212523
25222524 if return_cycle :
2523- return cycle , kwargs # needed for stem() to apply in a context()
2524- else :
2525- return kwargs
2525+ return cycle , kwargs
2526+ return kwargs
25262527
25272528 def _parse_level_lim (
25282529 self ,
@@ -3457,8 +3458,7 @@ def _apply_scatter(self, xs, ys, ss, cc, *, vert=True, **kwargs):
34573458 ys , kw = inputs ._dist_reduce (ys , ** kw )
34583459 ss , kw = self ._parse_markersize (ss , ** kw ) # parse 's'
34593460
3460- # Move _parse_cycle before _parse_color
3461- kw = self ._parse_cycle (xs .shape [1 ] if xs .ndim > 1 else 1 , ** kw )
3461+
34623462
34633463 # Only parse color if explicitly provided
34643464 infer_rgb = True
@@ -3480,6 +3480,10 @@ def _apply_scatter(self, xs, ys, ss, cc, *, vert=True, **kwargs):
34803480 infer_rgb = infer_rgb ,
34813481 ** kw ,
34823482 )
3483+ # Move _parse_cycle before _parse_color
3484+ kw = self ._parse_cycle (
3485+ xs .shape [1 ] if xs .ndim > 1 else 1 , cycle_manually = cycle_manually , ** kw
3486+ )
34833487
34843488 guide_kw = _pop_params (kw , self ._update_guide )
34853489 objs = []
0 commit comments