753
753
stack, stacked : bool, default: False
754
754
Whether to "stack" bars from successive columns of {y}
755
755
data or plot bars side-by-side in groups.
756
+ bar_labels : bool, default rc["bar.bar_labels"]
757
+ Whether to show the height values for vertical bars or width values for horizontal bars.
758
+ bar_labels_kw : dict, default None
759
+ Keywords to format the bar_labels, see :func:`~matplotlib.pyplot.bar_label`.
756
760
%(plot.args_1d_shared)s
757
761
758
762
Other parameters
@@ -4165,6 +4169,8 @@ def _apply_bar(
4165
4169
# Parse args
4166
4170
kw = kwargs .copy ()
4167
4171
kw , extents = self ._inbounds_extent (** kw )
4172
+ bar_labels = kw .pop ("bar_labels" , rc ["bar.bar_labels" ])
4173
+ bar_labels_kw = kw .pop ("bar_labels_kw" , {})
4168
4174
name = "barh" if orientation == "horizontal" else "bar"
4169
4175
stack = _not_none (stack = stack , stacked = stacked )
4170
4176
xs , hs , kw = self ._parse_1d_args (xs , hs , orientation = orientation , ** kw )
@@ -4212,6 +4218,10 @@ def _apply_bar(
4212
4218
obj = self ._call_negpos (name , x , h , w , b , use_zero = True , ** kw )
4213
4219
else :
4214
4220
obj = self ._call_native (name , x , h , w , b , ** kw )
4221
+ if bar_labels :
4222
+ if isinstance (obj , mcontainer .BarContainer ):
4223
+ self ._add_bar_labels (obj , orientation = orientation , ** bar_labels_kw )
4224
+
4215
4225
self ._fix_patch_edges (obj , ** edgefix_kw , ** kw )
4216
4226
for y in (b , b + h ):
4217
4227
self ._inbounds_xylim (extents , x , y , orientation = orientation )
@@ -4224,6 +4234,59 @@ def _apply_bar(
4224
4234
self ._update_guide (objs , ** guide_kw )
4225
4235
return objs [0 ] if len (objs ) == 1 else cbook .silent_list ("BarContainer" , objs )
4226
4236
4237
+ def _add_bar_labels (
4238
+ self ,
4239
+ container ,
4240
+ * ,
4241
+ orientation = "horizontal" ,
4242
+ ** kwargs ,
4243
+ ):
4244
+ """
4245
+ Automatically add bar labels and rescale the
4246
+ limits to produce a striking visual image.
4247
+ """
4248
+ # Drawing the labels does not rescale the limits to account
4249
+ # for the labels. We therefore first draw them and then
4250
+ # adjust the range for x or y depending on the orientation of the bar
4251
+ bar_labels = self ._call_native ("bar_label" , container , ** kwargs )
4252
+
4253
+ which = "x" if orientation == "horizontal" else "y"
4254
+ other_which = "y" if orientation == "horizontal" else "x"
4255
+
4256
+ # Get current limits
4257
+ current_lim = getattr (self , f"get_{ which } lim" )()
4258
+ other_lim = getattr (self , f"get_{ other_which } lim" )()
4259
+
4260
+ # Find the maximum extent of text + bar position
4261
+ max_extent = current_lim [1 ] # Start with current upper limit
4262
+
4263
+ for label , bar in zip (bar_labels , container ):
4264
+ # Get text bounding box
4265
+ bbox = label .get_window_extent (renderer = self .figure .canvas .get_renderer ())
4266
+ bbox_data = bbox .transformed (self .transData .inverted ())
4267
+
4268
+ if orientation == "horizontal" :
4269
+ # For horizontal bars, check if text extends beyond right edge
4270
+ bar_end = bar .get_width () + bar .get_x ()
4271
+ text_end = bar_end + bbox_data .width
4272
+ max_extent = max (max_extent , text_end )
4273
+ else :
4274
+ # For vertical bars, check if text extends beyond top edge
4275
+ bar_end = bar .get_height () + bar .get_y ()
4276
+ text_end = bar_end + bbox_data .height
4277
+ max_extent = max (max_extent , text_end )
4278
+
4279
+ # Only adjust limits if text extends beyond current range
4280
+ if max_extent > current_lim [1 ]:
4281
+ padding = (max_extent - current_lim [1 ]) * 1.25 # Add a bit of padding
4282
+ new_lim = (current_lim [0 ], max_extent + padding )
4283
+ getattr (self , f"set_{ which } lim" )(new_lim )
4284
+
4285
+ # Keep the other axis unchanged
4286
+ getattr (self , f"set_{ other_which } lim" )(other_lim )
4287
+
4288
+ return bar_labels
4289
+
4227
4290
@inputs ._preprocess_or_redirect ("x" , "height" , "width" , "bottom" )
4228
4291
@docstring ._concatenate_inherited
4229
4292
@docstring ._snippet_manager
0 commit comments