From e7a73fa16899ca013305e6f00bfe8abe69c0720f Mon Sep 17 00:00:00 2001 From: Hassan Kibirige Date: Fri, 6 Mar 2026 15:36:24 +0300 Subject: [PATCH] Add default parameter geom_blank to stat This allows us to extend stats with less boilerplate code. i.e. DEFAULT_PARAMS becomes optional. --- plotnine/geoms/geom.py | 19 +++++++++++-------- plotnine/stats/stat.py | 2 +- tests/test_stat.py | 12 ++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/plotnine/geoms/geom.py b/plotnine/geoms/geom.py index 86822034c3..1b71c027c9 100644 --- a/plotnine/geoms/geom.py +++ b/plotnine/geoms/geom.py @@ -118,7 +118,7 @@ def from_stat(stat: stat) -> geom: PlotnineError If unable to create a `geom`. """ - name = stat.params["geom"] + name = stat.params.get("geom", "blank") if isinstance(name, geom): return name @@ -494,18 +494,21 @@ def _verify_arguments(self, kwargs: dict[str, Any]): geom_stat_args = kwargs.keys() | self._stat._kwargs.keys() unknown = ( geom_stat_args - - self.aesthetics() - - self.DEFAULT_PARAMS.keys() # geom aesthetics - - self._stat.aesthetics() # geom parameters - - self._stat.DEFAULT_PARAMS.keys() # stat aesthetics - - { # stat parameters + - self.aesthetics() # geom aesthetics + - self.DEFAULT_PARAMS.keys() # geom parameters + - self._stat.aesthetics() # stat aesthetics + - self._stat.DEFAULT_PARAMS.keys() # stat parameters + - { + # stat parameters "data", "mapping", - "show_legend", # layer parameters + "geom", + # layer parameters + "show_legend", "inherit_aes", "raster", } - ) # layer parameters + ) if unknown: msg = ( "Parameters {}, are not understood by " diff --git a/plotnine/stats/stat.py b/plotnine/stats/stat.py index 43e49ecbaa..70a1e6c39e 100644 --- a/plotnine/stats/stat.py +++ b/plotnine/stats/stat.py @@ -42,7 +42,7 @@ class stat(ABC, metaclass=Register): NON_MISSING_AES: set[str] = set() """Required aesthetics for the stat""" - DEFAULT_PARAMS: dict[str, Any] = {} + DEFAULT_PARAMS: dict[str, Any] = {"geom": "blank"} """Required parameters for the stat""" CREATES: set[str] = set() diff --git a/tests/test_stat.py b/tests/test_stat.py index d60988fc9f..28cc67f25f 100644 --- a/tests/test_stat.py +++ b/tests/test_stat.py @@ -62,6 +62,18 @@ def draw(pinfo, panel_params, coord, ax, **kwargs): assert "weight" in g._stat.params +def test_stat_extending(): + class stat_xyz(stat): + REQUIRED_AES = {"x", "y"} + + def compute_group(self, data, scales): + return data + + p = ggplot(mtcars, aes("wt", "mpg")) + stat_xyz(geom="point", size=1) + + p.draw_test() # pyright: ignore[reportAttributeAccessIssue] + + def test_calculated_expressions(): p = ggplot(mtcars, aes(x="factor(cyl)", y="..count..+1")) + geom_bar() # No exception