GROUPED_BAR
Excel Usage
=GROUPED_BAR(data, title, xlabel, ylabel, grouped_colormap, orient, legend)
data(list[list], required): Input data (Labels, Val1, Val2…).title(str, optional, default: null): Chart title.xlabel(str, optional, default: null): Label for X-axis.ylabel(str, optional, default: null): Label for Y-axis.grouped_colormap(str, optional, default: “viridis”): Color map for groups.orient(str, optional, default: “v”): Orientation (‘v’ for vertical, ‘h’ for horizontal).legend(str, optional, default: “true”): Show legend.
Returns (object): Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).
Examples
Example 1: Basic grouped vertical bar chart
Inputs:
| data | legend | ||
|---|---|---|---|
| Q1 | 10 | 15 | true |
| Q2 | 20 | 25 | |
| Q3 | 15 | 20 |
Excel formula:
=GROUPED_BAR({"Q1",10,15;"Q2",20,25;"Q3",15,20}, "true")
Expected output:
"chart"
Example 2: Grouped horizontal bar chart
Inputs:
| data | orient | legend | ||
|---|---|---|---|---|
| A | 10 | 20 | h | true |
| B | 15 | 25 | ||
| C | 12 | 22 |
Excel formula:
=GROUPED_BAR({"A",10,20;"B",15,25;"C",12,22}, "h", "true")
Expected output:
"chart"
Example 3: Grouped bars with title and axis labels
Inputs:
| data | title | xlabel | ylabel | legend | ||
|---|---|---|---|---|---|---|
| 2020 | 100 | 150 | Sales Comparison | Year | Sales | true |
| 2021 | 120 | 180 | ||||
| 2022 | 140 | 200 |
Excel formula:
=GROUPED_BAR({2020,100,150;2021,120,180;2022,140,200}, "Sales Comparison", "Year", "Sales", "true")
Expected output:
"chart"
Example 4: Custom color map with multiple series
Inputs:
| data | grouped_colormap | legend | |||
|---|---|---|---|---|---|
| X | 5 | 10 | 15 | magma | true |
| Y | 8 | 12 | 18 | ||
| Z | 6 | 11 | 16 |
Excel formula:
=GROUPED_BAR({"X",5,10,15;"Y",8,12,18;"Z",6,11,16}, "magma", "true")
Expected output:
"chart"
Python Code
import sys
import matplotlib
IS_PYODIDE = sys.platform == "emscripten"
if IS_PYODIDE:
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import io
import base64
import numpy as np
import matplotlib.cm as cm
def grouped_bar(data, title=None, xlabel=None, ylabel=None, grouped_colormap='viridis', orient='v', legend='true'):
"""
Create a grouped/dodged bar chart from data.
See: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html
This example function is provided as-is without any representation of accuracy.
Args:
data (list[list]): Input data (Labels, Val1, Val2...).
title (str, optional): Chart title. Default is None.
xlabel (str, optional): Label for X-axis. Default is None.
ylabel (str, optional): Label for Y-axis. Default is None.
grouped_colormap (str, optional): Color map for groups. Valid options: Viridis, Plasma, Inferno, Magma, Cividis. Default is 'viridis'.
orient (str, optional): Orientation ('v' for vertical, 'h' for horizontal). Valid options: Vertical, Horizontal. Default is 'v'.
legend (str, optional): Show legend. Valid options: True, False. Default is 'true'.
Returns:
object: Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).
"""
try:
if not isinstance(data, list) or not data or not isinstance(data[0], list):
return "Error: Input data must be a 2D list."
if len(data[0]) < 2:
return "Error: Data must have at least 2 columns (Labels, Values)."
# Extract labels and series
labels = [str(row[0]) for row in data]
try:
series = []
for col_idx in range(1, len(data[0])):
series.append([float(row[col_idx]) for row in data])
except Exception:
return "Error: Values must be numeric."
if not series:
return "Error: No value columns found."
# Create figure
fig, ax = plt.subplots(figsize=(6, 4))
# Get colors from colormap
cmap = cm.get_cmap(grouped_colormap)
colors = [cmap(i / len(series)) for i in range(len(series))]
# Calculate bar positions
n_groups = len(labels)
n_bars = len(series)
bar_width = 0.8 / n_bars
x = np.arange(n_groups)
# Plot grouped bars
for i, s in enumerate(series):
offset = (i - n_bars / 2) * bar_width + bar_width / 2
if orient == 'v':
ax.bar(x + offset, s, bar_width, label=f"Series {i+1}", color=colors[i])
else:
ax.barh(x + offset, s, bar_width, label=f"Series {i+1}", color=colors[i])
# Set ticks and labels
if orient == 'v':
ax.set_xticks(x)
ax.set_xticklabels(labels)
else:
ax.set_yticks(x)
ax.set_yticklabels(labels)
# Set labels and title
if title:
ax.set_title(title)
if xlabel:
ax.set_xlabel(xlabel)
if ylabel:
ax.set_ylabel(ylabel)
# Legend
if legend == "true":
ax.legend()
plt.tight_layout()
if IS_PYODIDE:
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close(fig)
buf.seek(0)
img_bytes = buf.read()
img_b64 = base64.b64encode(img_bytes).decode('utf-8')
return f"data:image/png;base64,{img_b64}"
else:
return fig
except Exception as e:
return f"Error: {str(e)}"