Skip to content

Commit

Permalink
Set alpha properly on unfilled hist/kde plots (#2460)
Browse files Browse the repository at this point in the history
* Set alpha properly on unfilled hist/kde plots

Fixes #2450

* Fix typo in kdeplot docstring

* Generalize color comparison
  • Loading branch information
mwaskom authored Jan 31, 2021
1 parent 136b462 commit 548b854
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 75 deletions.
2 changes: 2 additions & 0 deletions doc/releases/v0.12.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ v0.12.0 (Unreleased)

- |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`).

- 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
2 changes: 1 addition & 1 deletion seaborn/_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(
Factor, multiplied by the smoothing bandwidth, that determines how
far the evaluation grid extends past the extreme datapoints. When
set to 0, truncate the curve at the data limits.
clip : pair of numbers None, or a pair of such pairs
clip : pair of numbers or None, or a pair of such pairs
Do not evaluate the density outside of these limits.
cumulative : bool, optional
If True, estimate a cumulative distribution function. Requires scipy.
Expand Down
19 changes: 19 additions & 0 deletions seaborn/_testing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
import matplotlib as mpl
from matplotlib.colors import to_rgb, to_rgba
from numpy.testing import assert_array_equal


Expand Down Expand Up @@ -69,3 +70,21 @@ def assert_plots_equal(ax1, ax2, labels=True):
if labels:
assert ax1.get_xlabel() == ax2.get_xlabel()
assert ax1.get_ylabel() == ax2.get_ylabel()


def assert_colors_equal(a, b, check_alpha=True):

def handle_array(x):

if isinstance(x, np.ndarray):
if x.ndim > 1:
x = np.unique(x, axis=0).squeeze()
if x.ndim > 1:
raise ValueError("Color arrays must be 1 dimensional")
return x

a = handle_array(a)
b = handle_array(b)

f = to_rgba if check_alpha else to_rgb
assert f(a) == f(b)
22 changes: 14 additions & 8 deletions seaborn/distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ def _artist_kws(self, kws, fill, element, multiple, color, alpha):
kws.setdefault("edgecolor", to_rgba(color, 1))
elif element == "bars":
kws["facecolor"] = "none"
kws["edgecolor"] = to_rgba(color, 1)
kws["edgecolor"] = to_rgba(color, alpha)
else:
kws["color"] = color
kws["color"] = to_rgba(color, alpha)
return kws

def _quantile_to_level(self, data, quantile):
Expand Down Expand Up @@ -502,12 +502,15 @@ def plot_univariate_histogram(
# Note: default linewidth is determined after plotting

# Default alpha should depend on other parameters
if multiple == "layer":
default_alpha = .5 if element == "bars" else .25
elif kde:
default_alpha = .5
if fill:
if multiple == "layer":
default_alpha = .5 if element == "bars" else .25
elif kde:
default_alpha = .5
else:
default_alpha = .75
else:
default_alpha = .75
default_alpha = 1
alpha = plot_kws.pop("alpha", default_alpha) # TODO make parameter?

hist_artists = []
Expand Down Expand Up @@ -914,7 +917,10 @@ def plot_univariate_density(
sticky_support = []

# XXX unfilled kdeplot is ignoring
default_alpha = .25 if multiple == "layer" else .75
if fill:
default_alpha = .25 if multiple == "layer" else .75
else:
default_alpha = 1
alpha = plot_kws.pop("alpha", default_alpha) # TODO make parameter?

# Now iterate through the subsets and draw the densities
Expand Down
21 changes: 10 additions & 11 deletions seaborn/tests/test_axisgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .. import axisgrid as ag
from .._testing import (
assert_plots_equal,
assert_colors_equal,
)

rs = np.random.RandomState(0)
Expand Down Expand Up @@ -224,7 +225,7 @@ def test_legend_data(self):
assert len(lines) == len(a_levels)

for line, hue in zip(lines, palette):
assert line.get_color() == hue
assert_colors_equal(line.get_color(), hue)

labels = g._legend.get_texts()
assert len(labels) == len(a_levels)
Expand All @@ -249,7 +250,7 @@ def test_legend_data_missing_level(self):
assert len(lines) == len(a_levels)

for line, hue in zip(lines, palette):
assert line.get_color() == hue
assert_colors_equal(line.get_color(), hue)

labels = g._legend.get_texts()
assert len(labels) == 4
Expand All @@ -273,7 +274,7 @@ def test_get_boolean_legend_data(self):
assert len(lines) == len(b_levels)

for line, hue in zip(lines, palette):
assert line.get_color() == hue
assert_colors_equal(line.get_color(), hue)

labels = g._legend.get_texts()
assert len(labels) == len(b_levels)
Expand Down Expand Up @@ -941,21 +942,20 @@ def test_map_diag_rectangular(self):
def test_map_diag_color(self):

color = "red"
rgb_color = mpl.colors.colorConverter.to_rgba(color)

g1 = ag.PairGrid(self.df)
g1.map_diag(plt.hist, color=color)

for ax in g1.diag_axes:
for patch in ax.patches:
assert patch.get_facecolor() == rgb_color
assert_colors_equal(patch.get_facecolor(), color)

g2 = ag.PairGrid(self.df)
g2.map_diag(kdeplot, color='red')

for ax in g2.diag_axes:
for line in ax.lines:
assert line.get_color() == color
assert_colors_equal(line.get_color(), color)

def test_map_diag_palette(self):

Expand All @@ -966,7 +966,7 @@ def test_map_diag_palette(self):

for ax in g.diag_axes:
for line, color in zip(ax.lines[::-1], pal):
assert line.get_color() == color
assert_colors_equal(line.get_color(), color)

def test_map_diag_and_offdiag(self):

Expand Down Expand Up @@ -1656,12 +1656,11 @@ def test_color(self):

g = ag.jointplot(x="x", y="y", data=self.data, color="purple")

purple = mpl.colors.colorConverter.to_rgb("purple")
scatter_color = g.ax_joint.collections[0].get_facecolor()[0, :3]
assert tuple(scatter_color) == purple
scatter_color = g.ax_joint.collections[0].get_facecolor()
assert_colors_equal(scatter_color, "purple")

hist_color = g.ax_marg_x.patches[0].get_facecolor()[:3]
assert hist_color == purple
assert_colors_equal(hist_color, "purple")

def test_palette(self, long_df):

Expand Down
Loading

0 comments on commit 548b854

Please sign in to comment.