Skip to content

Commit

Permalink
Allow presence of norm to force numeric interpretation of hue/size
Browse files Browse the repository at this point in the history
  • Loading branch information
mwaskom committed Jan 5, 2020
1 parent 537d42f commit 34ac2d9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
21 changes: 17 additions & 4 deletions seaborn/relational.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ def numeric_to_palette(self, data, order, palette, norm):
elif str(palette).startswith("ch:"):
args, kwargs = _parse_cubehelix_args(palette)
cmap = cubehelix_palette(0, *args, as_cmap=True, **kwargs)
elif isinstance(palette, dict):
colors = [palette[k] for k in sorted(palette)]
cmap = mpl.colors.ListedColormap(colors)
else:
try:
cmap = mpl.cm.get_cmap(palette)
Expand All @@ -263,7 +266,8 @@ def numeric_to_palette(self, data, order, palette, norm):

# TODO this should also use color_lookup, but that needs the
# class attributes that get set after using this function...
palette = dict(zip(levels, cmap(norm(levels))))
if not isinstance(palette, dict):
palette = dict(zip(levels, cmap(norm(levels))))
# palette = {l: cmap(norm([l, 1]))[0] for l in levels}

return levels, palette, cmap, norm
Expand Down Expand Up @@ -356,9 +360,11 @@ def parse_hue(self, data, palette, order, norm):
var_type = self._semantic_type(data)

# Override depending on the type of the palette argument
if isinstance(palette, (dict, list)):
if palette in QUAL_PALETTES:
var_type = "categorical"
elif palette in QUAL_PALETTES:
elif norm is not None:
var_type = "numeric"
elif isinstance(palette, (dict, list)):
var_type = "categorical"

# -- Option 1: categorical color palette
Expand Down Expand Up @@ -413,7 +419,9 @@ def parse_size(self, data, sizes, order, norm):
var_type = self._semantic_type(data)

# Override depending on the type of the sizes argument
if isinstance(sizes, (dict, list)):
if norm is not None:
var_type = "numeric"
elif isinstance(sizes, (dict, list)):
var_type = "categorical"

if var_type == "categorical":
Expand Down Expand Up @@ -479,6 +487,11 @@ def parse_size(self, data, sizes, order, norm):
# sizes = {l: min_width + norm(n) * (max_width - min_width)
# for l, n in zip(levels, numbers)}

if var_type == "categorical":
# Don't keep a reference to the norm, which will avoid
# downstream code from switching to numerical interpretation
norm = None

self.sizes = sizes
self.size_type = var_type
self.size_levels = levels
Expand Down
14 changes: 13 additions & 1 deletion seaborn/tests/test_relational.py
Original file line number Diff line number Diff line change
Expand Up @@ -1709,8 +1709,20 @@ def test_relplot_styles(self, long_df):
def test_relplot_stringy_numerics(self, long_df):

long_df["x_str"] = long_df["x"].astype(str)

g = rel.relplot(x="x", y="y", hue="x_str", data=long_df)
assert g._legend.texts[0].get_text() == "x_str"
points = g.ax.collections[0]
xys = points.get_offsets()
mask = np.ma.getmask(xys)
assert not mask.any()
assert np.array_equal(xys, long_df[["x", "y"]])

g = rel.relplot(x="x", y="y", size="x_str", data=long_df)
points = g.ax.collections[0]
xys = points.get_offsets()
mask = np.ma.getmask(xys)
assert not mask.any()
assert np.array_equal(xys, long_df[["x", "y"]])

def test_relplot_legend(self, long_df):

Expand Down

0 comments on commit 34ac2d9

Please sign in to comment.