@@ -982,7 +982,7 @@ def _add_colorbar(
982
982
"""
983
983
The driver function for adding axes colorbars.
984
984
"""
985
- # Parse input args
985
+ # Parse input arguments and apply defaults
986
986
# TODO: Get the 'best' inset colorbar location using the legend algorithm
987
987
# and implement inset colorbars the same as inset legends.
988
988
grid = _not_none (grid = grid , edges = edges , drawedges = drawedges , default = rc ['colorbar.grid' ]) # noqa: E501
@@ -1001,21 +1001,13 @@ def _add_colorbar(
1001
1001
ticklenratio = _not_none (ticklenratio , rc ['tick.lenratio' ])
1002
1002
tickwidthratio = _not_none (tickwidthratio , rc ['tick.widthratio' ])
1003
1003
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 = {}
1004
1008
locator_kw = locator_kw or {}
1005
1009
formatter_kw = formatter_kw or {}
1006
1010
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 = {}
1019
1011
for key , value in (
1020
1012
('size' , labelsize ),
1021
1013
('weight' , labelweight ),
@@ -1032,6 +1024,17 @@ def _add_colorbar(
1032
1024
):
1033
1025
if value is not None :
1034
1026
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
+ )
1035
1038
1036
1039
# Generate and prepare the colorbar axes
1037
1040
# NOTE: The inset axes function needs 'label' to know how to pad the box
@@ -1061,7 +1064,21 @@ def _add_colorbar(
1061
1064
result = cax ._parse_colorbar_arg (mappable , values , ** kwargs )
1062
1065
mappable , locator_default , formatter_default , kwargs = result
1063
1066
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
1065
1082
# NOTE: This uses DiscreteLocator for default discrete minor ticks
1066
1083
name = 'y' if kwargs .get ('orientation' ) == 'vertical' else 'x'
1067
1084
axis = cax .yaxis if kwargs .get ('orientation' ) == 'vertical' else cax .xaxis
@@ -1084,26 +1101,15 @@ def _add_colorbar(
1084
1101
tickminor = rc [name + 'tick.minor.visible' ]
1085
1102
if minorlocator is not None :
1086
1103
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
1091
1104
if isinstance (locator , mticker .NullLocator ) or not len (getattr (locator , 'locs' , (None ,))): # noqa: E501
1092
1105
minorlocator , tickminor = None , False # attempted fix
1093
1106
for ticker in (locator , formatter , minorlocator ):
1094
1107
if isinstance (ticker , mticker .TickHelper ):
1095
1108
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
1107
1113
kwargs .update (
1108
1114
{
1109
1115
'cax' : cax ,
@@ -1120,9 +1126,7 @@ def _add_colorbar(
1120
1126
else :
1121
1127
kwargs ['extend' ] = extend
1122
1128
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
1126
1130
# WARNING: Colorbar _ticker() internally makes dummy axis and updates view
1127
1131
# limits. Here we apply actual axis rather than dummy, otherwise default nbins
1128
1132
# of DiscreteLocator will not work. Not sure if this has side effects...
@@ -1135,13 +1139,17 @@ def _add_colorbar(
1135
1139
obj .minorticks_on ()
1136
1140
else :
1137
1141
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
1141
1142
if getattr (mappable .norm , 'descending' , None ):
1142
1143
axis .set_inverted (True )
1143
1144
if reverse : # potentially double reverse, although that would be weird...
1144
1145
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
1145
1153
if label is not None :
1146
1154
obj .set_label (label )
1147
1155
if labelloc is not None :
@@ -1158,7 +1166,7 @@ def _add_colorbar(
1158
1166
obj .solids .set_rasterized (rasterized )
1159
1167
cax ._fix_patch_edges (obj .solids , edgefix = edgefix )
1160
1168
1161
- # Return after registering location
1169
+ # Register location and return
1162
1170
self ._register_guide ('colorbar' , obj , (loc , align )) # possibly replace another
1163
1171
return obj
1164
1172
@@ -1256,6 +1264,8 @@ def _add_legend(
1256
1264
)
1257
1265
1258
1266
# 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.
1259
1269
if multi :
1260
1270
objs = lax ._parse_legend_centered (pairs , kw_frame = kw_frame , ** kwargs )
1261
1271
else :
@@ -1269,12 +1279,11 @@ def _add_legend(
1269
1279
lax .add_artist (obj )
1270
1280
1271
1281
# 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.
1274
1282
# WARNING: legendHandles only contains the *first* artist per legend because
1275
1283
# HandlerBase.legend_artist() called in Legend._init_legend_box() only
1276
1284
# returns the first artist. Instead we try to iterate through offset boxes.
1277
1285
for obj in objs :
1286
+ obj .set_clip_on (False ) # needed for tight bounding box calculations
1278
1287
box = getattr (obj , '_legend_handle_box' , None )
1279
1288
for obj in guides ._iter_children (box ):
1280
1289
if isinstance (obj , mtext .Text ):
@@ -1285,13 +1294,12 @@ def _add_legend(
1285
1294
kw ['sizes' ] = np .atleast_1d (kw_handle ['markersize' ])
1286
1295
obj .update (kw )
1287
1296
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
1291
1298
if isinstance (objs [0 ], mpatches .FancyBboxPatch ):
1292
1299
objs = objs [1 :]
1293
1300
obj = objs [0 ] if len (objs ) == 1 else tuple (objs )
1294
1301
self ._register_guide ('legend' , obj , (loc , align )) # possibly replace another
1302
+
1295
1303
return obj
1296
1304
1297
1305
def _apply_title_above (self ):
0 commit comments