Skip to content

Commit

Permalink
Fix histplot auto line width with log scale or categorical y axis (#2522
Browse files Browse the repository at this point in the history
)

* Fix histplot auto linewidth on log scaled axis

Fixes #2513

* Fix auto linewidth for categorical histograms on the y axis

Fixes #2523

(cherry picked from commit 0f538fb)
  • Loading branch information
mwaskom committed Aug 6, 2021
1 parent b5ccad9 commit 9776fb8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 10 deletions.
4 changes: 4 additions & 0 deletions doc/releases/v0.12.0.txt
Expand Up @@ -2,6 +2,7 @@ v0.12.0 (Unreleased)
--------------------

- |Fix| |Enhancement| Improved robustness to missing data, including additional support for the `pd.NA` type (:pr:`2417).

- |API| |Feature| |Enhancement| TODO (Flesh this out further). Increased flexibility of what can be shown by the internally-calculated errorbars (:pr:2407).

- |Fix| |Enhancement| Improved robustness to missing data, including additional support for the `pd.NA` type (:pr:`2417`).
Expand Down Expand Up @@ -29,8 +30,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:`histplot`, fixed two bugs where automatically computed edge widths were too thick for log-scaled histograms and categorical histograms on the y axis (:pr:2522`).

- |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`).
Expand Down
21 changes: 12 additions & 9 deletions seaborn/distributions.py
Expand Up @@ -658,15 +658,18 @@ def plot_univariate_histogram(
ax.autoscale_view()

# We will base everything on the minimum bin width
hist_metadata = [h.index.to_frame() for _, h in histograms.items()]
binwidth = min([
h["widths"].min() for h in hist_metadata
])

# Convert binwidtj from data coordinates to pixels
pts_x, pts_y = 72 / ax.figure.dpi * (
ax.transData.transform([binwidth, binwidth])
- ax.transData.transform([0, 0])
hist_metadata = pd.concat([
# Use .items for generality over dict or df
h.index.to_frame() for _, h in histograms.items()
]).reset_index(drop=True)
thin_bar_idx = hist_metadata["widths"].idxmin()
binwidth = hist_metadata.loc[thin_bar_idx, "widths"]
left_edge = hist_metadata.loc[thin_bar_idx, "edges"]

# Convert binwidth from data coordinates to pixels
pts_x, pts_y = 72 / ax.figure.dpi * abs(
ax.transData.transform([left_edge + binwidth] * 2)
- ax.transData.transform([left_edge] * 2)
)
if self.data_variable == "x":
binwidth_points = pts_x
Expand Down
14 changes: 13 additions & 1 deletion seaborn/tests/test_distributions.py
Expand Up @@ -886,7 +886,7 @@ def test_log_scale(self, rng):
for c1, c2 in zip(ax1.collections, ax2.collections):
assert_array_equal(c1.get_segments(), c2.get_segments())

def test_bandwiddth(self, rng):
def test_bandwidth(self, rng):

n = 100
x, y = rng.multivariate_normal([0, 0], [(.2, .5), (.5, 2)], n).T
Expand Down Expand Up @@ -1591,6 +1591,18 @@ def test_auto_linewidth(self, flat_series, fill):
histplot(flat_series, **kws, bins=30, ax=ax2)
assert get_lw(ax1) > get_lw(ax2)

f, ax1 = plt.subplots(figsize=(4, 5))
f, ax2 = plt.subplots(figsize=(4, 5))
histplot(flat_series, **kws, bins=30, ax=ax1)
histplot(10 ** flat_series, **kws, bins=30, log_scale=True, ax=ax2)
assert get_lw(ax1) == pytest.approx(get_lw(ax2))

f, ax1 = plt.subplots(figsize=(4, 5))
f, ax2 = plt.subplots(figsize=(4, 5))
histplot(y=[0, 1, 1], **kws, discrete=True, ax=ax1)
histplot(y=["a", "b", "b"], **kws, ax=ax2)
assert get_lw(ax1) == pytest.approx(get_lw(ax2))

def test_bar_kwargs(self, flat_series):

lw = 2
Expand Down

0 comments on commit 9776fb8

Please sign in to comment.