Skip to content

Commit

Permalink
ENH: Fewer spurious legend + after_scale warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
has2k1 committed May 6, 2024
1 parent f4c659d commit 470c1d2
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 18 deletions.
8 changes: 8 additions & 0 deletions doc/changelog.qmd
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
---
title: Changelog
---
## v0.13.6
(not-yet-released)

### Enhancements

- Stopped spurious warnings of the form ``PlotnineWarning: Failed to apply
`after_scale` modifications to the legend.`` when the `after_scale`
mapping is for another aesthetic.

## v0.13.5
(2024-04-26)
Expand Down
2 changes: 1 addition & 1 deletion plotnine/ggplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ def _build(self):
layout.setup_panel_params(self.coordinates)

# fill in the defaults
layers.use_defaults()
layers.use_defaults_after_scale()

# Allow stats to modify the layer data
layers.finish_statistics()
Expand Down
18 changes: 15 additions & 3 deletions plotnine/guides/guide_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,23 +160,35 @@ def create_geoms(self):
continue

matched = self.legend_aesthetics(l)
matched_set = set(matched)

# This layer does not contribute to the legend
if not set(matched) - exclude:
if not matched_set - exclude:
continue

data = self.key[matched].copy()

# Modify aesthetics

# When doing after_scale evaluations, we only consider those
# for the aesthetics of this legend. The reduces the spurious
# warnings where an evaluation of another aesthetic failed yet
# it is not needed.
aes_modifiers = {
ae: expr
for ae, expr in l.mapping._scaled.items()
if ae in matched_set
}

try:
data = l.use_defaults(data)
data = l.use_defaults(data, aes_modifiers)
except PlotnineError:
warn(
"Failed to apply `after_scale` modifications "
"to the legend.",
PlotnineWarning,
)
data = l.use_defaults(data, aes_modifiers={})
data = l.use_defaults(data, {})

# override.aes in guide_legend manually changes the geom
for ae in set(self.override_aes) & set(data.columns):
Expand Down
18 changes: 4 additions & 14 deletions plotnine/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,8 @@ def draw(self, layout: Layout, coord: coord):

def use_defaults(
self,
data: pd.DataFrame | None = None,
aes_modifiers: dict[str, Any] | None = None,
data: pd.DataFrame,
aes_modifiers: dict[str, Any],
) -> pd.DataFrame:
"""
Prepare/modify data for plotting
Expand All @@ -382,12 +382,6 @@ def use_defaults(
Expression to evaluate and replace aesthetics in
the data.
"""
if data is None:
data = self.data

if aes_modifiers is None:
aes_modifiers = self.mapping._scaled

return self.geom.use_defaults(data, aes_modifiers)

def finish_statistics(self):
Expand Down Expand Up @@ -474,13 +468,9 @@ def compute_position(self, layout: Layout):
for l in self:
l.compute_position(layout)

def use_defaults(
self,
data: pd.DataFrame | None = None,
aes_modifiers: dict[str, Any] | None = None,
):
def use_defaults_after_scale(self):
for l in self:
l.use_defaults(data, aes_modifiers)
l.use_defaults(l.data, l.mapping._scaled)

def transform(self, scales: Scales):
for l in self:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_guide_internals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import warnings

from plotnine import (
aes,
geom_point,
ggplot,
)
from plotnine.data import mtcars


def test_no_after_scale_warning():
p = ggplot(mtcars, aes("wt", "mpg")) + geom_point()

with warnings.catch_warnings():
warnings.simplefilter("error")
p.draw_test() # type: ignore

0 comments on commit 470c1d2

Please sign in to comment.