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

FIX: allow un-sharing categories in catplot #2196

Merged
merged 12 commits into from
Aug 20, 2020
2 changes: 2 additions & 0 deletions doc/releases/v0.11.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ Other

- Improved the error messages produced when categorical plots process the orientation parameter.

- Allowed :func:`catplot` to not unify categories across facets if the categorical axis is not shared (i.e. by specifying ``sharex=False``) (:pr:`2196`).

- Fixed a bug in :class:`PairGrid` that appeared when setting ``corner=True`` and ``despine=False`` (:pr:`2203`).

- Removed an optional (an undocumented) dependency on BeautifulSoup (:pr:`2190`).
Expand Down
3 changes: 1 addition & 2 deletions seaborn/axisgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -2369,8 +2369,7 @@ def jointplot(
:context: close-figs

>>> g = sns.jointplot(x="petal_length", y="sepal_length", data=iris,
... marginal_kws=dict(bins=15, rug=True),
... marker="+")
... marginal_kws=dict(bins=15), marker="+")

"""
# Avoid circular import
Expand Down
27 changes: 21 additions & 6 deletions seaborn/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -3768,7 +3768,6 @@ def catplot(
"box": _BoxPlotter,
"violin": _ViolinPlotter,
"boxen": _LVPlotter,
"lv": _LVPlotter,
"bar": _BarPlotter,
"point": _PointPlotter,
"strip": _StripPlotter,
Expand All @@ -3778,7 +3777,23 @@ def catplot(
p = _CategoricalPlotter()
p.require_numeric = plotter_class.require_numeric
p.establish_variables(x_, y_, hue, data, orient, order, hue_order)
order = p.group_names
if (
order is not None
or (sharex and p.orient == "v")
or (sharey and p.orient == "h")
):
# Sync categorical axis between facets to have the same categories
order = p.group_names
elif color is None and hue is None:
msg = (
"Setting `{}=False` with `color=None` may cause different levels of the "
"`{}` variable to share colors. This will change in a future version."
)
if not sharex and p.orient == "v":
warnings.warn(msg.format("sharex", "x"), UserWarning)
if not sharey and p.orient == "h":
warnings.warn(msg.format("sharey", "y"), UserWarning)

hue_order = p.hue_names

# Determine the palette to use
Expand Down Expand Up @@ -3893,10 +3908,10 @@ def catplot(
row_order, col_order : lists of strings, optional
Order to organize the rows and/or columns of the grid in, otherwise the
orders are inferred from the data objects.
kind : string, optional
The kind of plot to draw (corresponds to the name of a categorical
plotting function. Options are: "point", "bar", "strip", "swarm",
"box", "violin", or "boxen".
kind : str, optional
The kind of plot to draw, corresponds to the name of a categorical
axes-level plotting function. Options are: "strip", "swarm", "box", "violin",
"boxen", "point", "bar", or "count".
{height}
{aspect}
{orient}
Expand Down
2 changes: 1 addition & 1 deletion seaborn/distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2510,8 +2510,8 @@ def distplot(a=None, bins=None, hist=True, kde=True, rug=False, fit=None,
Change the color of all the plot elements:

.. plot::

:context: close-figs

>>> sns.set_color_codes()
>>> ax = sns.distplot(x, color="y")

Expand Down
47 changes: 46 additions & 1 deletion seaborn/tests/test_categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .. import palettes


class CategoricalFixture(object):
class CategoricalFixture:
"""Test boxplot (also base class for things like violinplots)."""
rs = np.random.RandomState(30)
n_total = 60
Expand Down Expand Up @@ -2607,6 +2607,51 @@ def test_factorplot(self):
want_lines = self.g.unique().size + 1
nt.assert_equal(len(g.ax.lines), want_lines)

def test_share_xy(self):

# Test default behavior works
g = cat.catplot(x="g", y="y", col="g", data=self.df, sharex=True)
for ax in g.axes.flat:
assert len(ax.collections) == len(self.df.g.unique())

g = cat.catplot(x="y", y="g", col="g", data=self.df, sharey=True)
for ax in g.axes.flat:
assert len(ax.collections) == len(self.df.g.unique())

# Test unsharing works
with pytest.warns(UserWarning):
g = cat.catplot(x="g", y="y", col="g", data=self.df, sharex=False)
for ax in g.axes.flat:
assert len(ax.collections) == 1

with pytest.warns(UserWarning):
g = cat.catplot(x="y", y="g", col="g", data=self.df, sharey=False)
for ax in g.axes.flat:
assert len(ax.collections) == 1

# Make sure no warning is raised if color is provided on unshared plot
with pytest.warns(None) as record:
g = cat.catplot(
x="g", y="y", col="g", data=self.df, sharex=False, color="b"
)
assert not len(record)

with pytest.warns(None) as record:
g = cat.catplot(
x="y", y="g", col="g", data=self.df, sharey=False, color="r"
)
assert not len(record)

# Make sure order is used if given, regardless of sharex value
order = self.df.g.unique()
g = cat.catplot(x="g", y="y", col="g", data=self.df, sharex=False, order=order)
for ax in g.axes.flat:
assert len(ax.collections) == len(self.df.g.unique())

g = cat.catplot(x="y", y="g", col="g", data=self.df, sharey=False, order=order)
for ax in g.axes.flat:
assert len(ax.collections) == len(self.df.g.unique())


class TestBoxenPlotter(CategoricalFixture):

Expand Down