@@ -3077,18 +3077,14 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3077
3077
This function is new in v3.11, and the API is still provisional.
3078
3078
We may still fine-tune some aspects based on user-feedback.
3079
3079
3080
- This is a convenience function to plot bars for multiple datasets.
3081
- In particular, it simplifies positioning of the bars compared to individual
3082
- `~.Axes.bar` plots.
3083
-
3084
3080
Bar plots present categorical data as a sequence of bars, one bar per category.
3085
- We call one set of such values a *dataset* and it's bars all share the same
3081
+ We call one set of such values a *dataset* and its bars all share the same
3086
3082
color. Grouped bar plots show multiple such datasets, where the values per
3087
3083
category are grouped together. The category names are drawn as tick labels
3088
3084
below the bar groups. Each dataset has a distinct bar color, and can optionally
3089
3085
get a label that is used for the legend.
3090
3086
3091
- Here is an example call structure and the corresponding plot :
3087
+ Example :
3092
3088
3093
3089
.. code-block:: python
3094
3090
@@ -3098,6 +3094,10 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3098
3094
3099
3095
.. plot:: _embedded_plots/grouped_bar.py
3100
3096
3097
+ ``grouped_bar()`` is a high-level plotting function for grouped bar charts.
3098
+ Use `~.Axes.bar` instead if you need finer grained control on individual bar
3099
+ positions or widths.
3100
+
3101
3101
Parameters
3102
3102
----------
3103
3103
heights : list of array-like or dict of array-like or 2D array \
@@ -3121,25 +3121,20 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3121
3121
- dict of array-like: A mapping from names to datasets. Each dataset
3122
3122
(dict value) must have the same number of elements.
3123
3123
3124
- This is similar to passing a list of array-like, with the addition that
3125
- each dataset gets a name.
3126
-
3127
3124
Example call:
3128
3125
3129
3126
.. code-block:: python
3130
3127
3131
3128
grouped_bar({'ds0': dataset_0, 'ds1': dataset_1, 'ds2': dataset_2]})
3132
3129
3133
- The names are used as *labels*, i.e. the following two calls are
3134
- equivalent :
3130
+ The names are used as *labels*, which is equivalent to passing in a dict
3131
+ of array-like :
3135
3132
3136
3133
.. code-block:: python
3137
3134
3138
- data_dict = {'ds0': dataset_0, 'ds1': dataset_1, 'ds2': dataset_2]}
3139
- grouped_bar(data_dict)
3140
3135
grouped_bar(data_dict.values(), labels=data_dict.keys())
3141
3136
3142
- When using a dict-like input, you must not pass *labels* explicitly.
3137
+ When using a dict input, you must not pass *labels* explicitly.
3143
3138
3144
3139
- a 2D array: The rows are the categories, the columns are the different
3145
3140
datasets.
@@ -3154,21 +3149,16 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3154
3149
3155
3150
.. code-block:: python
3156
3151
3157
- group_labels = ["group_A ", "group_B "]
3152
+ categories = ["A ", "B "]
3158
3153
dataset_labels = ["dataset_0", "dataset_1", "dataset_2"]
3159
3154
array = np.random.random((2, 3))
3160
-
3161
- Note that this is consistent with pandas. These two calls produce
3162
- the same bar plot structure:
3163
-
3164
- .. code-block:: python
3165
-
3166
3155
grouped_bar(array, tick_labels=categories, labels=dataset_labels)
3167
- df = pd.DataFrame(array, index=categories, columns=dataset_labels)
3168
- df.plot.bar()
3169
3156
3170
3157
- a `pandas.DataFrame`.
3171
3158
3159
+ The index is used for the categories, the columns are used for the
3160
+ datasets.
3161
+
3172
3162
.. code-block:: python
3173
3163
3174
3164
df = pd.DataFrame(
@@ -3178,6 +3168,9 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3178
3168
)
3179
3169
grouped_bar(df)
3180
3170
3171
+ # is equivalent to
3172
+ grouped_bar(df.to_numpy(), tick_labels=df.index, labels=df.columns)
3173
+
3181
3174
Note that ``grouped_bar(df)`` produces a structurally equivalent plot like
3182
3175
``df.plot.bar()``.
3183
3176
@@ -3187,9 +3180,8 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3187
3180
3188
3181
tick_labels : list of str, optional
3189
3182
The category labels, which are placed on ticks at the center *positions*
3190
- of the bar groups.
3191
-
3192
- If not set, the axis ticks (positions and labels) are left unchanged.
3183
+ of the bar groups. If not set, the axis ticks (positions and labels) are
3184
+ left unchanged.
3193
3185
3194
3186
labels : list of str, optional
3195
3187
The labels of the datasets, i.e. the bars within one group.
@@ -3249,7 +3241,7 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3249
3241
aspects. ``bar(x, y)`` is a lower-level API and places bars with height *y*
3250
3242
at explicit positions *x*. It also allows to specify individual bar widths
3251
3243
and colors. This kind of detailed control and flexibility is difficult to
3252
- manage and often not needed when plotting multiple datasets as grouped bar
3244
+ manage and often not needed when plotting multiple datasets as a grouped bar
3253
3245
plot. Therefore, ``grouped_bar`` focusses on the abstraction of bar plots
3254
3246
as visualization of categorical data.
3255
3247
@@ -3309,8 +3301,18 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3309
3301
heights = heights .T
3310
3302
3311
3303
num_datasets = len (heights )
3312
- dataset_0 = next (iter (heights ))
3313
- num_groups = len (dataset_0 )
3304
+ num_groups = len (next (iter (heights ))) # inferred from first dataset
3305
+
3306
+ # validate that all datasets have the same length, i.e. num_groups
3307
+ # - can be skipped if heights is an array
3308
+ if not hasattr (heights , 'shape' ):
3309
+ for i , dataset in enumerate (heights ):
3310
+ if len (dataset ) != num_groups :
3311
+ raise ValueError (
3312
+ "'heights' contains datasets with different number of "
3313
+ f"elements. dataset 0 has { num_groups } elements but "
3314
+ f"dataset { i } has { len (dataset )} elements."
3315
+ )
3314
3316
3315
3317
if positions is None :
3316
3318
group_centers = np .arange (num_groups )
@@ -3325,13 +3327,6 @@ def grouped_bar(self, heights, *, positions=None, group_spacing=1.5, bar_spacing
3325
3327
else :
3326
3328
group_distance = 1
3327
3329
3328
- for i , dataset in enumerate (heights ):
3329
- if len (dataset ) != num_groups :
3330
- raise ValueError (
3331
- f"'x' indicates { num_groups } groups, but dataset { i } "
3332
- f"has { len (dataset )} groups"
3333
- )
3334
-
3335
3330
_api .check_in_list (["vertical" , "horizontal" ], orientation = orientation )
3336
3331
3337
3332
if colors is None :
0 commit comments