Skip to content

fix(bar): percentage_by_bar_group fails when an x value repeats #598

Open

Description

@murray-ds

What: bar.plot(..., data_label_format="percentage_by_bar_group") fails when an x value repeats: ValueError: zip() argument 2 is shorter than argument 1. It fails the same way with sort_order set, and when the repeated values are the index. Checked on main @ c5f4b2a.

A repeated x is valid input: pandas draws one bar per row, and the other label formats work. The docstring says this mode shows "each bar's share of its x-axis group".

Cause: bar.py:219 computes df.groupby(x_col)[value_col].sum().sum(axis=1), one total per x value. _generate_percentage_labels then zips that against every bar with strict=True. The fix needs one denominator per row, e.g. groupby(x_col)[value_col].transform("sum").sum(axis=1).

Failing test:

import matplotlib

matplotlib.use("Agg")

import matplotlib.pyplot as plt
import pandas as pd
import pytest

from openretailscience.plots import bar


@pytest.fixture(autouse=True)
def cleanup_figures():
    yield
    plt.close("all")


class TestBarPercentageByBarGroupRepeatedX:
    @pytest.mark.parametrize("use_index", [False, True])
    def test_labels_are_share_of_x_group(self, use_index):
        """Leeds 10/30 splits 25%/75%; York 20/20 splits 50%/50%."""
        df = pd.DataFrame(
            {
                "store": ["Leeds", "Leeds", "York", "York"],
                "channel": ["web", "shop", "web", "shop"],
                "revenue": [10.0, 30.0, 20.0, 20.0],
            },
        )
        x_col = "store"
        if use_index:
            df = df.set_index("store")
            x_col = None
        ax = bar.plot(df, value_col="revenue", x_col=x_col, data_label_format="percentage_by_bar_group")
        labels = [float(t.get_text().rstrip("%")) for t in ax.texts]
        assert labels == [25.0, 75.0, 50.0, 50.0]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions