Repository: mwaskom/seaborn

Issue:
histplot with small bins becames black by cluttering of rectangle edges when using x axis in log scale
### Description
When increasing the number of values on a 1D histogram, the number of bins increase and they become smaller. In general, when that happens the rectangle edges disappear so that the distribution preserves the colour of the rectangles.

When using logarithmic scale for the x axis, however, the rectangle edges are maintained and the distribution ends up appearing black.

### Versions
seaborn 0.11.1
matplotlib 3.3.3

### Example

```python
fig, axs = plt.subplots(ncols=3, nrows=2, figsize=(12,6))

vals = np.random.randn(1000)
sns.histplot(x=vals, log_scale=(False, False), ax=axs[0, 0])
sns.histplot(x=10**vals, log_scale=(True, False), ax=axs[1, 0])

vals = np.random.randn(10000)
sns.histplot(x=vals, log_scale=(False, False), ax=axs[0, 1])
sns.histplot(x=10**vals, log_scale=(True, False), ax=axs[1, 1])

vals = np.random.randn(1000000)
sns.histplot(x=vals, log_scale=(False, False), ax=axs[0, 2])
sns.histplot(x=10**vals, log_scale=(True, False), ax=axs[1, 2])

plt.tight_layout()
```

![histplot_black](https://user-images.githubusercontent.com/6085431/111771649-3af7c180-88ac-11eb-9028-9c4fa6fe6ddf.png)



Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=h1) Report
> Merging [#2522](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=desc) (3628b8a) into [master](https://codecov.io/gh/mwaskom/seaborn/commit/6d84f82b8edeb00963d74fa5e29b5c9fc3e7248c?el=desc) (6d84f82) will **decrease** coverage by `0.52%`.
> The diff coverage is `100.00%`.

> :exclamation: Current head 3628b8a differs from pull request most recent head 1549935. Consider uploading reports for the commit 1549935 to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/mwaskom/seaborn/pull/2522/graphs/tree.svg?width=650&height=150&src=pr&token=SLuzHnA9Bl)](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2522      +/-   ##
==========================================
- Coverage   97.45%   96.93%   -0.53%     
==========================================
  Files          17       17              
  Lines        6323     6293      -30     
==========================================
- Hits         6162     6100      -62     
- Misses        161      193      +32     
```


| [Impacted Files](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [seaborn/distributions.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9kaXN0cmlidXRpb25zLnB5) | `96.35% <100.00%> (-0.01%)` | :arrow_down: |
| [seaborn/algorithms.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9hbGdvcml0aG1zLnB5) | `87.50% <0.00%> (-12.50%)` | :arrow_down: |
| [seaborn/utils.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi91dGlscy5weQ==) | `92.85% <0.00%> (-1.71%)` | :arrow_down: |
| [seaborn/\_statistics.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9fc3RhdGlzdGljcy5weQ==) | `98.43% <0.00%> (-1.57%)` | :arrow_down: |
| [seaborn/matrix.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9tYXRyaXgucHk=) | `94.95% <0.00%> (-0.92%)` | :arrow_down: |
| [seaborn/regression.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9yZWdyZXNzaW9uLnB5) | `97.15% <0.00%> (-0.65%)` | :arrow_down: |
| [seaborn/\_core.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9fY29yZS5weQ==) | `98.05% <0.00%> (-0.57%)` | :arrow_down: |
| [seaborn/categorical.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9jYXRlZ29yaWNhbC5weQ==) | `98.31% <0.00%> (-0.23%)` | :arrow_down: |
| [seaborn/axisgrid.py](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree#diff-c2VhYm9ybi9heGlzZ3JpZC5weQ==) | `95.57% <0.00%> (-0.05%)` | :arrow_down: |
| ... and [3 more](https://codecov.io/gh/mwaskom/seaborn/pull/2522/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=footer). Last update [6d84f82...1549935](https://codecov.io/gh/mwaskom/seaborn/pull/2522?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/doc/releases/v0.12.0.txt b/doc/releases/v0.12.0.txt
index b506c8fd..d552f874 100644
--- a/doc/releases/v0.12.0.txt
+++ b/doc/releases/v0.12.0.txt
@@ -30,6 +30,8 @@ v0.12.0 (Unreleased)
 
 - |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`).
diff --git a/seaborn/distributions.py b/seaborn/distributions.py
index 821926f1..ac7add72 100644
--- a/seaborn/distributions.py
+++ b/seaborn/distributions.py
@@ -644,15 +644,18 @@ class _DistributionPlotter(VectorPlotter):
                 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
-                ])
+                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 * (
-                    ax.transData.transform([binwidth, binwidth])
-                    - ax.transData.transform([0, 0])
+                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


Test patch:
diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py
index 063c0ff1..a11b2aa9 100644
--- a/seaborn/tests/test_distributions.py
+++ b/seaborn/tests/test_distributions.py
@@ -940,7 +940,7 @@ class TestKDEPlotBivariate:
         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
@@ -1675,6 +1675,18 @@ class TestHistPlotUnivariate(SharedAxesLevelTests):
         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