diff --git a/doc/releases/v0.12.0.txt b/doc/releases/v0.12.0.txt index 1a140359e4..68a7c7c93c 100644 --- a/doc/releases/v0.12.0.txt +++ b/doc/releases/v0.12.0.txt @@ -29,6 +29,11 @@ v0.12.0 (Unreleased) - |Fix| In :func:`histplot` and :func:`kdeplot`, fixed a bug where the `multiple` was ignored when `hue` was provided as a vector without a name (:pr:`2462`). - |Defaults| In :func:`displot`, the default alpha value now adjusts to a provided `multiple` parameter even when `hue` is not assigned (:pr:`2462`). +- |Fix| In :func:`histplot`, fixed a bug where using `shrink` with non-discrete bins shifted bar positions inaccurately (:pr:`2477`). + +- |Fix| In :func:`displot`, fixed a bug where `common_norm` was ignored when `kind="hist"` and faceting was used without assigning `hue` (:pr:`2468`). + +- |Defaults| In :func:`displot`, the default alpha value now adjusts to a provided `multiple` parameter even when `hue` is not assigned (: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`). diff --git a/seaborn/distributions.py b/seaborn/distributions.py index 9f8ba62a01..9a9cdb5037 100644 --- a/seaborn/distributions.py +++ b/seaborn/distributions.py @@ -446,9 +446,12 @@ def plot_univariate_histogram( edges = np.power(10, edges) # Pack the histogram data and metadata together + orig_widths = np.diff(edges) + widths = shrink * orig_widths + edges = edges[:-1] + (1 - shrink) / 2 * orig_widths index = pd.MultiIndex.from_arrays([ - pd.Index(edges[:-1], name="edges"), - pd.Index(np.diff(edges) * shrink, name="widths"), + pd.Index(edges, name="edges"), + pd.Index(widths, name="widths"), ]) hist = pd.Series(heights, index=index, name="heights") @@ -551,9 +554,8 @@ def plot_univariate_histogram( # Use matplotlib bar plotting plot_func = ax.bar if self.data_variable == "x" else ax.barh - move = .5 * (1 - shrink) artists = plot_func( - hist["edges"] + move, + hist["edges"], hist["heights"] - bottom, hist["widths"], bottom, diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py index ec01fac640..6f3014851e 100644 --- a/seaborn/tests/test_distributions.py +++ b/seaborn/tests/test_distributions.py @@ -1520,10 +1520,21 @@ def test_weights_with_auto_bins(self, long_df): def test_shrink(self, long_df): + f, (ax1, ax2) = plt.subplots(2) + bw = 2 - shrink = .5 - ax = histplot(long_df, x="x", binwidth=bw, shrink=shrink) - assert ax.patches[0].get_width() == bw * shrink + shrink = .4 + + histplot(long_df, x="x", binwidth=bw, ax=ax1) + histplot(long_df, x="x", binwidth=bw, shrink=shrink, ax=ax2) + + for p1, p2 in zip(ax1.patches, ax2.patches): + + w1, w2 = p1.get_width(), p2.get_width() + assert w2 == pytest.approx(shrink * w1) + + x1, x2 = p1.get_x(), p2.get_x() + assert (x2 + w2 / 2) == pytest.approx(x1 + w1 / 2) def test_log_scale_explicit(self, rng):