Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f47d748

Browse filesBrowse files
committed
Add support for numeric x
1 parent d8847ec commit f47d748
Copy full SHA for f47d748

File tree

2 files changed

+42
-9
lines changed
Filter options

2 files changed

+42
-9
lines changed

‎galleries/examples/lines_bars_and_markers/grouped_bar_chart.py

Copy file name to clipboardExpand all lines: galleries/examples/lines_bars_and_markers/grouped_bar_chart.py
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,19 @@
102102
#
103103
# df = pd.DataFrame(data, index=x, columns=columns)
104104
# df.plot.bar()
105+
106+
# %%
107+
# Numeric x values
108+
# ----------------
109+
# In the most common case, one will want to pass categorical labels as *x*.
110+
# Additionally, we allow numeric values for *x*, as with `~.Axes.bar()`.
111+
# But for simplicity and clarity, we require that these are equidistant.
112+
113+
x = [0, 2, 4]
114+
data = {
115+
'data1': [1, 2, 3],
116+
'data2': [1.2, 2.2, 3.2],
117+
}
118+
119+
fig, ax = plt.subplots()
120+
ax.grouped_bar(x, data)

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+26-9Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,8 +3017,12 @@ def grouped_bar(self, x, heights, dataset_labels=None):
30173017
"""
30183018
Parameters
30193019
-----------
3020-
x : array-like of str
3021-
The labels.
3020+
x : array-like or list of str
3021+
The center positions of the bar groups. If these are numeric values,
3022+
they have to be equidistant. As with `~.Axes.bar`, you can provide
3023+
categorical labels, which will be used at integer numeric positions
3024+
``range(x)``.
3025+
30223026
heights : list of array-like or dict of array-like or 2D array
30233027
The heights for all x and groups. One of:
30243028
@@ -3077,27 +3081,40 @@ def grouped_bar(self, x, heights, dataset_labels=None):
30773081
elif hasattr(heights, 'shape'):
30783082
heights = heights.T
30793083

3080-
num_labels = len(x)
3084+
num_groups = len(x)
30813085
num_datasets = len(heights)
30823086

3083-
for dataset in heights:
3084-
assert len(dataset) == num_labels
3087+
if isinstance(x[0], str):
3088+
tick_labels = x
3089+
group_centers = np.arange(num_groups)
3090+
else:
3091+
if num_groups > 1:
3092+
d = np.diff(x)
3093+
if not np.allclose(d, d.mean()):
3094+
raise ValueError("'x' must be equidistant")
3095+
group_centers = np.asarray(x)
3096+
tick_labels = None
3097+
3098+
for i, dataset in enumerate(heights):
3099+
if len(dataset) != num_groups:
3100+
raise ValueError(
3101+
f"'x' indicates {num_groups} groups, but dataset {i} "
3102+
f"has {len(dataset)} groups"
3103+
)
30853104

30863105
margin = 0.1
30873106
bar_width = (1 - 2 * margin) / num_datasets
3088-
block_centers = np.arange(num_labels)
30893107

30903108
if dataset_labels is None:
30913109
dataset_labels = [None] * num_datasets
30923110
else:
30933111
assert len(dataset_labels) == num_datasets
30943112

30953113
for i, (hs, dataset_label) in enumerate(zip(heights, dataset_labels)):
3096-
lefts = block_centers - 0.5 + margin + i * bar_width
3097-
print(i, x, lefts, hs, dataset_label)
3114+
lefts = group_centers - 0.5 + margin + i * bar_width
30983115
self.bar(lefts, hs, width=bar_width, align="edge", label=dataset_label)
30993116

3100-
self.xaxis.set_ticks(block_centers, labels=x)
3117+
self.xaxis.set_ticks(group_centers, labels=tick_labels)
31013118

31023119
# TODO: does not return anything for now
31033120

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.