Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PairGrid errors with hue assigned in map #2590

Closed
StRuoff opened this issue May 20, 2021 · 3 comments · Fixed by #2847
Closed

PairGrid errors with hue assigned in map #2590

StRuoff opened this issue May 20, 2021 · 3 comments · Fixed by #2847

Comments

@StRuoff
Copy link

StRuoff commented May 20, 2021

In seaborn version 0.9.0 I was able to use the following Code to plot scatterplots across a PairGrid with categorical hue. The reason I am not using the "hue" keyword in creating the PairGrid is, that I want one regression line (with regplot) and not one regression per hue-category.

import seaborn as sns
iris = sns.load_dataset("iris")
g = sns.PairGrid(iris, y_vars=["sepal_length","sepal_width"], x_vars=["petal_length","petal_width"])
g.map(sns.scatterplot, hue=iris["species"])
g.map(sns.regplot, scatter=False)

However, since I updated to searbon 0.11.1 the following Error message occurs:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/_core.py in _lookup_single(self, key)
    143             # Use a value that's in the original data vector
--> 144             value = self.lookup_table[key]
    145         except KeyError:

KeyError: 'setosa'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/_core.py in _lookup_single(self, key)
    148             try:
--> 149                 normed = self.norm(key)
    150             except TypeError as err:

TypeError: 'NoneType' object is not callable

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-3-46dd21e9c95a> in <module>
      2 iris = sns.load_dataset("iris")
      3 g = sns.PairGrid(iris, y_vars=["sepal_length","sepal_width"], x_vars=["petal_length","species"])
----> 4 g.map(sns.scatterplot, hue=iris["species"])
      5 

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/axisgrid.py in map(self, func, **kwargs)
   1263         row_indices, col_indices = np.indices(self.axes.shape)
   1264         indices = zip(row_indices.flat, col_indices.flat)
-> 1265         self._map_bivariate(func, indices, **kwargs)
   1266 
   1267         return self

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/axisgrid.py in _map_bivariate(self, func, indices, **kwargs)
   1463             if ax is None:  # i.e. we are in corner mode
   1464                 continue
-> 1465             self._plot_bivariate(x_var, y_var, ax, func, **kws)
   1466         self._add_axis_labels()
   1467 

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/axisgrid.py in _plot_bivariate(self, x_var, y_var, ax, func, **kwargs)
   1503         kwargs.setdefault("hue_order", self._hue_order)
   1504         kwargs.setdefault("palette", self._orig_palette)
-> 1505         func(x=x, y=y, **kwargs)
   1506 
   1507         self._update_legend_data(ax)

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/_decorators.py in inner_f(*args, **kwargs)
     44             )
     45         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 46         return f(**kwargs)
     47     return inner_f
     48 

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/relational.py in scatterplot(x, y, hue, style, size, data, palette, hue_order, hue_norm, sizes, size_order, size_norm, markers, style_order, x_bins, y_bins, units, estimator, ci, n_boot, alpha, x_jitter, y_jitter, legend, ax, **kwargs)
    818     p._attach(ax)
    819 
--> 820     p.plot(ax, kwargs)
    821 
    822     return ax

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/relational.py in plot(self, ax, kws)
    626         # Apply the mapping from semantic variables to artist attributes
    627         if "hue" in self.variables:
--> 628             c = self._hue_map(data["hue"])
    629 
    630         if "size" in self.variables:

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/_core.py in __call__(self, key, *args, **kwargs)
     61         """Get the attribute(s) values for the data key."""
     62         if isinstance(key, (list, np.ndarray, pd.Series)):
---> 63             return [self._lookup_single(k, *args, **kwargs) for k in key]
     64         else:
     65             return self._lookup_single(key, *args, **kwargs)

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/_core.py in <listcomp>(.0)
     61         """Get the attribute(s) values for the data key."""
     62         if isinstance(key, (list, np.ndarray, pd.Series)):
---> 63             return [self._lookup_single(k, *args, **kwargs) for k in key]
     64         else:
     65             return self._lookup_single(key, *args, **kwargs)

~/.Software/miniforge3/envs/py3.9/lib/python3.8/site-packages/seaborn/_core.py in _lookup_single(self, key)
    149                 normed = self.norm(key)
    150             except TypeError as err:
--> 151                 if np.isnan(key):
    152                     value = (0, 0, 0, 0)
    153                 else:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

My further observations are:

  • the error does not occur when using the "hue" keyword when creating PairGrid
  • the error does not occur for numerical values for hue
  • changing the dtype to "categorical" does not help

Edit:
I tried all versions between 0.9.0 and the current release (0.11.1) and the error only occurs in the current release. If I use 0.11.0, the plot seems to work.

@jhncls
Copy link

jhncls commented May 20, 2021

The following workarounds seem to work:

g.map(sns.scatterplot, hue=iris["species"], hue_order=iris["species"].unique())

or

g.map(lambda x, y, **kwargs: sns.scatterplot(x=x, y=y, hue=iris["species"]))

@mwaskom mwaskom added this to the v0.12.0 milestone May 20, 2021
@StRuoff
Copy link
Author

StRuoff commented May 20, 2021

g.map(sns.scatterplot, hue=iris["species"], hue_order=iris["species"].unique())

The workaround fixes the problem for me.
Thank you very much!

@mwaskom Should I close the Issue or leave it open until the bug is fixed?

@mwaskom
Copy link
Owner

mwaskom commented May 20, 2021

That's a good workaround, but it's still a bug. The problem is that PairGrid now lets hue at the grid-level delegate to the axes-level functions if they have hue in their signature. But it's not properly handling the case where hue is not set for the grid, but is specified for one mapped function. @jhncls's workaround suggests the fix.

An easier workaround would have been to set PairGrid(..., hue="species") and then pass .map(..., hue=None) where you don't want to separate by species. But regplot is the one axis-level function that does not yet handle hue-mapping internally, so it doesn't work for this specific case. It would have if you wanted a single bivariate density over hue-mapped scatterplot points (i.e. this example or something similar.

@mwaskom mwaskom changed the title Mapping scatterplot to PairGrid fails for categorical hue PairGrid errors with hue assigned in map May 24, 2021
mwaskom added a commit that referenced this issue Jun 11, 2022
mwaskom added a commit that referenced this issue Jun 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants