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)}"

Online Calculator