Skip to content

fix(stat_summary_bin): emit the fallback warning instead of building it - #1129

Merged
has2k1 merged 1 commit into
has2k1:mainfrom
Rodrigo-Palma:fix/summary-bin-fallback-warning
Sep 26, 2026
Merged

has2k1 merged 1 commit into
has2k1:mainfrom
Rodrigo-Palma:fix/summary-bin-fallback-warning

Conversation

@Rodrigo-Palma

Copy link
Copy Markdown
Contributor

The bug

stat_summary_bin.setup_params builds a PlotnineWarning and throws it away:

def setup_params(self, data):
    keys = ("fun_data", "fun_y", "fun_ymin", "fun_ymax")
    if not any(self.params[k] for k in keys):
        PlotnineWarning(                                  # instantiated, never raised
            "No summary function, supplied, defaulting to mean_se()"
        )
        self.params["fun_data"] = "mean_se"

There is no warn(...), and the module does not even import it, so the fallback to mean_se() happens in complete silence:

>>> s = stat_summary_bin(bins=5)
>>> s.setup_params(df)
before   : None
warnings : []
after    : mean_se

It is the only instantiated-and-discarded warning or exception in plotnine/:

$ grep -rnE "^\s+(PlotnineWarning|PlotnineError|UserWarning)\(" --include="*.py" plotnine/
plotnine/stats/stat_summary_bin.py:110:            PlotnineWarning(

Why it is an oversight and not a decision

Three independent signals:

  1. The commit that wrote the line. 827fd09 ("Add default function to stat_summary_bin", closes stat_summary_bin no default summary function #528) deliberately turned an error into a warning, switching the import along with it:

    -from ..exceptions import PlotnineError
    +from ..exceptions import PlotnineWarning
    ...
    -            raise PlotnineError('No summary function')
    +            PlotnineWarning(
    +                "No summary function, supplied, defaulting to mean_se()"
    +            )
    +            self.params['fun_data'] = 'mean_se'

    The message was written on purpose; only the warn() call never made it in. The raise that used to make this visible went away and nothing took its place.

  2. The sibling. stat_summary.setup_params still raises on the very same condition (identical keys tuple and if not any(...) block), and every other warning in plotnine/stats/ goes through warn(msg, PlotnineWarning).

  3. ggplot2 informs here. R/stat-summary-bin.R: cli::cli_inform("No summary function supplied, defaulting to {.fn mean_se}"). The wording in plotnine is the same sentence, stray comma aside.

What it costs in practice: someone who mistypes the argument, fun= instead of fun_y= coming from ggplot2 3.4+, gets error bars nobody asked for and no hint that a default was substituted.

The change

Call warn, and drop the stray comma while the line is being touched, which makes the message read exactly like ggplot2's.

Test

test_no_summary_function_warns asserts the warning via p._build(), the same way tests/test_stat.py does.

Before the fix:

E       Failed: DID NOT WARN. No warnings of type (<class 'plotnine.exceptions.PlotnineWarning'>,) were emitted.
1 failed

After: 4 passed in that file.

Full suite with the fix: 906 passed, 5 skipped, 1 xpassed, including tests/test_lint_and_format.py. The new warning surfaces in the existing test_setting_binwidth, which is exactly the documented fallback and does not fail anything, since the project does not set filterwarnings = error.

`setup_params` constructs `PlotnineWarning(...)` and drops it on the
floor, so falling back to `mean_se()` happens in complete silence.

The commit that introduced this (827fd09, "Add default function to
stat_summary_bin") replaced `raise PlotnineError("No summary function")`
with the warning and even switched the import, so announcing the
fallback was the intent; only the `warn()` call is missing. The sibling
`stat_summary.setup_params` still raises on the same condition, and
ggplot2 informs here too (`R/stat-summary-bin.R`: "No summary function
supplied, defaulting to mean_se").

It matters because a misspelled argument, `fun=` instead of `fun_y=`
for instance, silently yields a plausible and wrong plot.

The stray comma in the message goes away with it, making the wording
match ggplot2's.
@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.50%. Comparing base (cb81719) to head (3d6b7bc).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1129   +/-   ##
=======================================
  Coverage   88.50%   88.50%           
=======================================
  Files         226      226           
  Lines       16613    16614    +1     
  Branches     2130     2130           
=======================================
+ Hits        14703    14704    +1     
  Misses       1295     1295           
  Partials      615      615           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@has2k1
has2k1 merged commit 95bf021 into has2k1:main Sep 26, 2026
8 checks passed
@has2k1

has2k1 commented Sep 26, 2026

Copy link
Copy Markdown
Owner

@Rodrigo-Palma, thank you.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stat_summary_bin no default summary function

2 participants