From d45cdbae04c0e47cf83c20d178181128db056325 Mon Sep 17 00:00:00 2001 From: Hassan Kibirige Date: Tue, 10 Dec 2024 17:51:54 +0300 Subject: [PATCH] Transform aesthetic parameters --- doc/changelog.qmd | 10 ++++++ plotnine/geoms/geom.py | 2 +- plotnine/ggplot.py | 2 +- plotnine/layer.py | 17 ++++++++-- .../transform_aes_defaults_and_params.png | Bin 0 -> 8635 bytes .../transform_datetime_aes_param.png | Bin 0 -> 7152 bytes tests/test_scale_internals.py | 31 ++++++++++++++++++ 7 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 tests/baseline_images/test_scale_internals/transform_aes_defaults_and_params.png create mode 100644 tests/baseline_images/test_scale_internals/transform_datetime_aes_param.png diff --git a/doc/changelog.qmd b/doc/changelog.qmd index 54ee61cb4..657922196 100644 --- a/doc/changelog.qmd +++ b/doc/changelog.qmd @@ -13,6 +13,16 @@ title: Changelog - Fixed [](:class:`~plotnine.geom_text`) with `adjust_text` for some cases where the text are placed outside the panels. {{< issue 899 >}} +- The default aesthetics and aesthetic parameters of geoms (and stats) are + now transformed. So you can now set date values as aesthetic parameters. + e.g. + + ```python + geom_point(y=datetime(2024, 12, 11)) + ``` + + if the `y` aesthetic is mapped to datetime column in another layer. + ## v0.14.3 (2024-11-26) [![](https://zenodo.org/badge/DOI/10.5281/zenodo.14224336.svg)](https://doi.org/10.5281/zenodo.14224336) diff --git a/plotnine/geoms/geom.py b/plotnine/geoms/geom.py index 269063f9a..8d4733dc5 100644 --- a/plotnine/geoms/geom.py +++ b/plotnine/geoms/geom.py @@ -217,7 +217,7 @@ def use_defaults( data : Data used for drawing the geom. aes_modifiers : - Aesthetics + Aesthetics to evaluate Returns ------- diff --git a/plotnine/ggplot.py b/plotnine/ggplot.py index 44b36aa42..aba115d9b 100755 --- a/plotnine/ggplot.py +++ b/plotnine/ggplot.py @@ -406,7 +406,7 @@ def _build(self): layout.setup_panel_params(self.coordinates) # fill in the defaults - layers.use_defaults_after_scale() + layers.use_defaults_after_scale(scales) # Allow stats to modify the layer data layers.finish_statistics() diff --git a/plotnine/layer.py b/plotnine/layer.py index b8ef910de..4d7e240a7 100644 --- a/plotnine/layer.py +++ b/plotnine/layer.py @@ -370,6 +370,7 @@ def use_defaults( self, data: pd.DataFrame, aes_modifiers: dict[str, Any], + scales: Scales | None = None, ) -> pd.DataFrame: """ Prepare/modify data for plotting @@ -382,7 +383,17 @@ def use_defaults( Expression to evaluate and replace aesthetics in the data. """ - return self.geom.use_defaults(data, aes_modifiers) + old_columns = data.columns + data = self.geom.use_defaults(data, aes_modifiers) + if scales is not None: + # The default aesthetics and the aesthetic parameters are + # specified in userspace. When we add them we have to + # transform them. + new_columns = data.columns.difference(old_columns) + _data = scales.transform_df(self.data[new_columns]) + for col in new_columns: + data[col] = _data[col] + return data def finish_statistics(self): """ @@ -468,9 +479,9 @@ def compute_position(self, layout: Layout): for l in self: l.compute_position(layout) - def use_defaults_after_scale(self): + def use_defaults_after_scale(self, scales: Scales): for l in self: - l.use_defaults(l.data, l.mapping._scaled) + l.data = l.use_defaults(l.data, l.mapping._scaled, scales) def transform(self, scales: Scales): for l in self: diff --git a/tests/baseline_images/test_scale_internals/transform_aes_defaults_and_params.png b/tests/baseline_images/test_scale_internals/transform_aes_defaults_and_params.png new file mode 100644 index 0000000000000000000000000000000000000000..dd79a29b07ebf91b46a9628c054304d4bbc1bea0 GIT binary patch literal 8635 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

aZ`r(uT9CCfpA-^sDnQk_eDw}}q{{Xo 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 i{1K_)A3Hc2y^2%NDud^ud*JIE