Skip to content

Commit

Permalink
Fix multiple resolution when hue variable has no name
Browse files Browse the repository at this point in the history
Fixes #2452

(cherry picked from commit 008f7e0e030681f8047c7d628e6bb3fc3d23e6ff)
  • Loading branch information
mwaskom committed Feb 1, 2021
1 parent d0acb8c commit dc30328
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
4 changes: 3 additions & 1 deletion doc/releases/v0.12.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ v0.12.0 (Unreleased)

- |Enhancement| In :func:`histplot`, added `stat="percent"` as an option for normalization such that bar heights sum to 100 (:pr:`2461`).

- |Enhancement| |Fix| Improved integration with the matplotlib color cycle in most axes-level functions (:pr:`2449`).

- |Fix| In :func:`lineplot, allowed the `dashes` keyword to set the style of a line without mapping a `style` variable (:pr:`2449`).

- |Fix| In :func:`rugplot`, fixed a bug that prevented the use of datetime data (:pr:`2458`).

- |Fix| In :func:`histplot` and :func:`kdeplot`, fixed a bug where the `alpha` parameter was ignored when `fill=False` (:pr:`2460`).

- |Fix| |Enhancement| Improved integration with the matplotlib color cycle in most axes-level functions (:pr:`2449`).
- |Fix| In :func:`histplot` and :func:`kdeplot`, fixed a bug where the `multiple` was ignored when `hue` was provided a vector without a name (:pr:`2462`).

- Made `scipy` an optional dependency and added `pip install seaborn[all]` as a method for ensuring the availability of compatible `scipy` and `statsmodels` libraries at install time. This has a few minor implications for existing code, which are explained in the Github pull request (:pr:`2398`).

Expand Down
26 changes: 19 additions & 7 deletions seaborn/distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ def has_xy_data(self):
# TODO see above points about where this should go
return bool({"x", "y"} & set(self.variables))

def _redundant_with_facets(self, var):
"""Return True if var is assigned and is redundant with faceting variables."""
# TODO likely generally useful but only used in this module for now.
return any(
self.plot_data[var].equals(self.plot_data[facet_var])
for facet_var in ["row", "col"]
if var in self.plot_data and facet_var in self.plot_data
)

def _add_legend(
self,
ax_obj, artist, fill, element, multiple, alpha, artist_kws, legend_kws,
Expand Down Expand Up @@ -413,11 +422,8 @@ def plot_univariate_histogram(
else:
common_norm = False

# Turn multiple off if no hue or if hue exists but is redundant with faceting
facet_vars = [self.variables.get(var, None) for var in ["row", "col"]]
if "hue" not in self.variables:
multiple = None
elif self.variables["hue"] in facet_vars:
# Let default alpha look like single histogram if hue is redundant
if self._redundant_with_facets("hue"):
multiple = None

# Estimate the smoothed kernel densities, for use later
Expand Down Expand Up @@ -886,6 +892,13 @@ def plot_univariate_density(
# Input checking
_check_argument("multiple", ["layer", "stack", "fill"], multiple)

# Let default alpha look like single density with redundant hue
if self._redundant_with_facets("hue"):
# Note unlike histplot, we set this to layer rather than None because
# default alpha for layer matches default alpha for a single density.
# But that's kind of messy and we should rethink.
multiple = "layer"

# Always share the evaluation grid when stacking
subsets = bool(set(self.variables) - {"x", "y"})
if subsets and multiple in ("stack", "fill"):
Expand Down Expand Up @@ -916,9 +929,8 @@ def plot_univariate_density(
else:
sticky_support = []

# XXX unfilled kdeplot is ignoring
if fill:
default_alpha = .25 if multiple == "layer" else .75
default_alpha = .25 if multiple in "layer" else .75
else:
default_alpha = 1
alpha = plot_kws.pop("alpha", default_alpha) # TODO make parameter?
Expand Down
11 changes: 11 additions & 0 deletions seaborn/tests/test_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,17 @@ def test_hue_dodge(self, long_df):
assert_array_almost_equal(layer_xs[1], dodge_xs[1])
assert_array_almost_equal(layer_xs[0], dodge_xs[0] - bw / 2)

def test_hue_as_numpy_dodged(self, long_df):
# https://github.com/mwaskom/seaborn/issues/2452

ax = histplot(
long_df,
x="y", hue=long_df["a"].to_numpy(),
multiple="dodge", bins=1,
)
# Note hue order reversal
assert ax.patches[1].get_x() < ax.patches[0].get_x()

def test_multiple_input_check(self, flat_series):

with pytest.raises(ValueError, match="`multiple` must be"):
Expand Down

0 comments on commit dc30328

Please sign in to comment.