@@ -982,7 +982,7 @@ def _add_colorbar(
982982 """
983983 The driver function for adding axes colorbars.
984984 """
985- # Parse input args
985+ # Parse input arguments and apply defaults
986986 # TODO: Get the 'best' inset colorbar location using the legend algorithm
987987 # and implement inset colorbars the same as inset legends.
988988 grid = _not_none (grid = grid , edges = edges , drawedges = drawedges , default = rc ['colorbar.grid' ]) # noqa: E501
@@ -1001,21 +1001,13 @@ def _add_colorbar(
10011001 ticklenratio = _not_none (ticklenratio , rc ['tick.lenratio' ])
10021002 tickwidthratio = _not_none (tickwidthratio , rc ['tick.widthratio' ])
10031003 rasterized = _not_none (rasterized , rc ['colorbar.rasterized' ])
1004+
1005+ # Build label and locator keyword argument dicts
1006+ # NOTE: This carefully handles the 'maxn' and 'maxn_minor' deprecations
1007+ kw_label = {}
10041008 locator_kw = locator_kw or {}
10051009 formatter_kw = formatter_kw or {}
10061010 minorlocator_kw = minorlocator_kw or {}
1007- for b , kw in enumerate ((locator_kw , minorlocator_kw )):
1008- key = 'maxn_minor' if b else 'maxn'
1009- name = 'minorlocator' if b else 'locator'
1010- nbins = kwargs .pop ('maxn_minor' if b else 'maxn' , None )
1011- if nbins is not None :
1012- kw ['nbins' ] = nbins
1013- warnings ._warn_proplot (
1014- f'The colorbar() keyword { key !r} was deprecated in v0.10. To '
1015- "achieve the same effect, you can pass 'nbins' to the new default "
1016- f"locator DiscreteLocator using { name } _kw={{'nbins': { nbins } }}."
1017- )
1018- kw_label = {}
10191011 for key , value in (
10201012 ('size' , labelsize ),
10211013 ('weight' , labelweight ),
@@ -1032,6 +1024,17 @@ def _add_colorbar(
10321024 ):
10331025 if value is not None :
10341026 kw_ticklabels [key ] = value
1027+ for b , kw in enumerate ((locator_kw , minorlocator_kw )):
1028+ key = 'maxn_minor' if b else 'maxn'
1029+ name = 'minorlocator' if b else 'locator'
1030+ nbins = kwargs .pop ('maxn_minor' if b else 'maxn' , None )
1031+ if nbins is not None :
1032+ kw ['nbins' ] = nbins
1033+ warnings ._warn_proplot (
1034+ f'The colorbar() keyword { key !r} was deprecated in v0.10. To '
1035+ "achieve the same effect, you can pass 'nbins' to the new default "
1036+ f"locator DiscreteLocator using { name } _kw={{'nbins': { nbins } }}."
1037+ )
10351038
10361039 # Generate and prepare the colorbar axes
10371040 # NOTE: The inset axes function needs 'label' to know how to pad the box
@@ -1061,7 +1064,21 @@ def _add_colorbar(
10611064 result = cax ._parse_colorbar_arg (mappable , values , ** kwargs )
10621065 mappable , locator_default , formatter_default , kwargs = result
10631066
1064- # Parse ticking keyword arguments
1067+ # Parse 'extendsize' and 'extendfrac' keywords
1068+ # TODO: Make this auto-adjust to the subplot size
1069+ if extendsize is not None and extendfrac is not None :
1070+ warnings ._warn_proplot (
1071+ f'You cannot specify both an absolute extendsize={ extendsize !r} '
1072+ f"and a relative extendfrac={ extendfrac !r} . Ignoring 'extendfrac'."
1073+ )
1074+ extendfrac = None
1075+ if extendfrac is None :
1076+ width , height = cax ._get_size_inches ()
1077+ scale = height if kwargs .get ('orientation' ) == 'vertical' else width
1078+ extendsize = units (extendsize , 'em' , 'in' )
1079+ extendfrac = extendsize / max (scale - 2 * extendsize , units (1 , 'em' , 'in' ))
1080+
1081+ # Parse the tick locators and formatters
10651082 # NOTE: This uses DiscreteLocator for default discrete minor ticks
10661083 name = 'y' if kwargs .get ('orientation' ) == 'vertical' else 'x'
10671084 axis = cax .yaxis if kwargs .get ('orientation' ) == 'vertical' else cax .xaxis
@@ -1084,26 +1101,15 @@ def _add_colorbar(
10841101 tickminor = rc [name + 'tick.minor.visible' ]
10851102 if minorlocator is not None :
10861103 minorlocator = constructor .Locator (minorlocator , ** minorlocator_kw )
1087-
1088- # Prepare colorbar keyword arguments
1089- # WARNING: Critical to not pass empty major locators in matplotlib < 3.5
1090- # See: https://github.com/lukelbd/proplot/issues/301
10911104 if isinstance (locator , mticker .NullLocator ) or not len (getattr (locator , 'locs' , (None ,))): # noqa: E501
10921105 minorlocator , tickminor = None , False # attempted fix
10931106 for ticker in (locator , formatter , minorlocator ):
10941107 if isinstance (ticker , mticker .TickHelper ):
10951108 ticker .set_axis (axis )
1096- if extendsize is not None and extendfrac is not None :
1097- warnings ._warn_proplot (
1098- f'You cannot specify both an absolute extendsize={ extendsize !r} '
1099- f"and a relative extendfrac={ extendfrac !r} . Ignoring 'extendfrac'."
1100- )
1101- extendfrac = None
1102- if extendfrac is None :
1103- width , height = cax ._get_size_inches ()
1104- scale = height if kwargs .get ('orientation' ) == 'vertical' else width
1105- extendsize = units (extendsize , 'em' , 'in' )
1106- extendfrac = extendsize / max (scale - 2 * extendsize , units (1 , 'em' , 'in' ))
1109+
1110+ # Prepare colorbar keyword arguments
1111+ # WARNING: Critical to not pass empty major locators in matplotlib < 3.5
1112+ # See: https://github.com/lukelbd/proplot/issues/301
11071113 kwargs .update (
11081114 {
11091115 'cax' : cax ,
@@ -1120,9 +1126,7 @@ def _add_colorbar(
11201126 else :
11211127 kwargs ['extend' ] = extend
11221128
1123- # Draw and update the colorbar
1124- # WARNING: Must use colorbar set_label to set text,
1125- # calling set_text on the axis will do nothing!
1129+ # Create colorbar and update ticks and axis direction
11261130 # WARNING: Colorbar _ticker() internally makes dummy axis and updates view
11271131 # limits. Here we apply actual axis rather than dummy, otherwise default nbins
11281132 # of DiscreteLocator will not work. Not sure if this has side effects...
@@ -1135,13 +1139,17 @@ def _add_colorbar(
11351139 obj .minorticks_on ()
11361140 else :
11371141 obj .minorticks_off ()
1138- axis .set_tick_params (which = 'both' , color = color , direction = tickdir )
1139- axis .set_tick_params (which = 'major' , length = ticklen , width = tickwidth )
1140- axis .set_tick_params (which = 'minor' , length = ticklen * ticklenratio , width = tickwidth * tickwidthratio ) # noqa: E501
11411142 if getattr (mappable .norm , 'descending' , None ):
11421143 axis .set_inverted (True )
11431144 if reverse : # potentially double reverse, although that would be weird...
11441145 axis .set_inverted (True )
1146+
1147+ # Update other colorbar settings
1148+ # WARNING: Must use colorbar set_label to set text,
1149+ # calling set_text on the axis will do nothing!
1150+ axis .set_tick_params (which = 'both' , color = color , direction = tickdir )
1151+ axis .set_tick_params (which = 'major' , length = ticklen , width = tickwidth )
1152+ axis .set_tick_params (which = 'minor' , length = ticklen * ticklenratio , width = tickwidth * tickwidthratio ) # noqa: E501
11451153 if label is not None :
11461154 obj .set_label (label )
11471155 if labelloc is not None :
@@ -1158,7 +1166,7 @@ def _add_colorbar(
11581166 obj .solids .set_rasterized (rasterized )
11591167 cax ._fix_patch_edges (obj .solids , edgefix = edgefix )
11601168
1161- # Return after registering location
1169+ # Register location and return
11621170 self ._register_guide ('colorbar' , obj , (loc , align )) # possibly replace another
11631171 return obj
11641172
@@ -1256,6 +1264,8 @@ def _add_legend(
12561264 )
12571265
12581266 # Add the legend and update patch properties
1267+ # TODO: Add capacity for categorical labels in a single legend like seaborn
1268+ # rather than manual handle overrides with multiple legends.
12591269 if multi :
12601270 objs = lax ._parse_legend_centered (pairs , kw_frame = kw_frame , ** kwargs )
12611271 else :
@@ -1269,12 +1279,11 @@ def _add_legend(
12691279 lax .add_artist (obj )
12701280
12711281 # Update legend patch and elements
1272- # TODO: Add capacity for categorical labels in a single legend like seaborn
1273- # rather than manual handle overrides with multiple legends.
12741282 # WARNING: legendHandles only contains the *first* artist per legend because
12751283 # HandlerBase.legend_artist() called in Legend._init_legend_box() only
12761284 # returns the first artist. Instead we try to iterate through offset boxes.
12771285 for obj in objs :
1286+ obj .set_clip_on (False ) # needed for tight bounding box calculations
12781287 box = getattr (obj , '_legend_handle_box' , None )
12791288 for obj in guides ._iter_children (box ):
12801289 if isinstance (obj , mtext .Text ):
@@ -1285,13 +1294,12 @@ def _add_legend(
12851294 kw ['sizes' ] = np .atleast_1d (kw_handle ['markersize' ])
12861295 obj .update (kw )
12871296
1288- # Return after registering location
1289- for obj in objs :
1290- obj .set_clip_on (False ) # critical for tight bounding box calcs
1297+ # Register location and return
12911298 if isinstance (objs [0 ], mpatches .FancyBboxPatch ):
12921299 objs = objs [1 :]
12931300 obj = objs [0 ] if len (objs ) == 1 else tuple (objs )
12941301 self ._register_guide ('legend' , obj , (loc , align )) # possibly replace another
1302+
12951303 return obj
12961304
12971305 def _apply_title_above (self ):
0 commit comments