Skip to content

Commit

Permalink
Downgrade exception on mapping list length mismatch to warning (#2856)
Browse files Browse the repository at this point in the history
* Downgrade exception on mapping list length mismatch to warning

* Lint

* Fix pairplot test

* Set stacklevel to report warning in user code
  • Loading branch information
mwaskom authored Jun 15, 2022
1 parent 26bf4b3 commit 563e96d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
38 changes: 27 additions & 11 deletions seaborn/_oldcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,30 @@ def map(cls, plotter, *args, **kwargs):
setattr(plotter, method_name, cls(plotter, *args, **kwargs))
return plotter

def _check_list_length(self, levels, values, variable):
"""Input check when values are provided as a list."""
# Copied from _core/properties; eventually will be replaced for that.
message = ""
if len(levels) > len(values):
message = " ".join([
f"\nThe {variable} list has fewer values ({len(values)})",
f"than needed ({len(levels)}) and will cycle, which may",
"produce an uninterpretable plot."
])
values = [x for _, x in zip(levels, itertools.cycle(values))]

elif len(values) > len(levels):
message = " ".join([
f"The {variable} list has more values ({len(values)})",
f"than needed ({len(levels)}), which may not be intended.",
])
values = values[:len(levels)]

if message:
warnings.warn(message, UserWarning, stacklevel=6)

return values

def _lookup_single(self, key):
"""Apply the mapping to a single data value."""
return self.lookup_table[key]
Expand Down Expand Up @@ -212,10 +236,7 @@ def categorical_mapping(self, data, palette, order):
else:
colors = color_palette("husl", n_colors)
elif isinstance(palette, list):
if len(palette) != n_colors:
err = "The palette list has the wrong number of colors."
raise ValueError(err)
colors = palette
colors = self._check_list_length(levels, palette, "palette")
else:
colors = color_palette(palette, n_colors)

Expand Down Expand Up @@ -367,10 +388,7 @@ def categorical_mapping(self, data, sizes, order):
elif isinstance(sizes, list):

# List inputs give size values in the same order as the levels
if len(sizes) != len(levels):
err = "The `sizes` list has the wrong number of values."
raise ValueError(err)

sizes = self._check_list_length(levels, sizes, "sizes")
lookup_table = dict(zip(levels, sizes))

else:
Expand Down Expand Up @@ -578,9 +596,7 @@ def _map_attributes(self, arg, levels, defaults, attr):
raise ValueError(err)
lookup_table = arg
elif isinstance(arg, Sequence):
if len(levels) != len(arg):
err = f"The `{attr}` argument has the wrong number of values"
raise ValueError(err)
arg = self._check_list_length(levels, arg, attr)
lookup_table = dict(zip(levels, arg))
elif arg:
err = f"This `{attr}` argument was not understood: {arg}"
Expand Down
2 changes: 1 addition & 1 deletion tests/test_axisgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -1385,7 +1385,7 @@ def test_pairplot_markers(self):
m2 = g._legend.legendHandles[1].get_paths()[0]
assert m1 != m2

with pytest.raises(ValueError):
with pytest.warns(UserWarning):
g = ag.pairplot(self.df, hue="a", vars=vars, markers=markers[:-2])

def test_corner_despine(self):
Expand Down
12 changes: 6 additions & 6 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def test_hue_map_categorical(self, wide_df, long_df):

# Test list with wrong number of colors
palette = colors[:-1]
with pytest.raises(ValueError):
with pytest.warns(UserWarning):
HueMapping(p, palette=palette)

# Test hue order
Expand Down Expand Up @@ -296,7 +296,7 @@ def test_hue_map_numeric(self, long_df):
assert m.lookup_table == dict(zip(hue_levels, palette))

palette = color_palette("Blues", len(hue_levels) + 1)
with pytest.raises(ValueError):
with pytest.warns(UserWarning):
HueMapping(p, palette=palette)

# Test dictionary of colors
Expand Down Expand Up @@ -460,7 +460,7 @@ def test_map_size_categorical(self, long_df):

# Test sizes list with wrong length
sizes = list(np.random.rand(len(levels) + 1))
with pytest.raises(ValueError):
with pytest.warns(UserWarning):
SizeMapping(p, sizes=sizes)

# Test sizes dict with missing levels
Expand Down Expand Up @@ -578,13 +578,13 @@ def test_map_style(self, long_df):
assert_array_equal(m(key, "path").vertices, path.vertices)

# Test too many levels with style lists
with pytest.raises(ValueError):
with pytest.warns(UserWarning):
StyleMapping(p, markers=["o", "s"], dashes=False)

with pytest.raises(ValueError):
with pytest.warns(UserWarning):
StyleMapping(p, markers=False, dashes=[(2, 1)])

# Test too many levels with style dicts
# Test missing keys with style dicts
markers, dashes = {"a": "o", "b": "s"}, False
with pytest.raises(ValueError):
StyleMapping(p, markers=markers, dashes=dashes)
Expand Down

0 comments on commit 563e96d

Please sign in to comment.