Repository: mwaskom/seaborn

Issue:
displot(kind='ecdf',..., log_scale=True) not working
The following line of code gives an error:

```
sns.displot(kind='ecdf', data=df, x='col_1', log_scale=True)

UserWarning: Data has no positive values, and therefore cannot be log-scaled.
```


My data is all positive and kind='hist' or 'kde' works just fine.



Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2504?src=pr&el=h1) Report
> Merging [#2504](https://codecov.io/gh/mwaskom/seaborn/pull/2504?src=pr&el=desc) (e60fea9) into [master](https://codecov.io/gh/mwaskom/seaborn/commit/ba4bd0fa0a90b2bd00cb62c2b4a5e38013a73ac6?el=desc) (ba4bd0f) will **decrease** coverage by `0.47%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/mwaskom/seaborn/pull/2504/graphs/tree.svg?width=650&height=150&src=pr&token=SLuzHnA9Bl)](https://codecov.io/gh/mwaskom/seaborn/pull/2504?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2504      +/-   ##
==========================================
- Coverage   97.45%   96.97%   -0.48%     
==========================================
  Files          17       17              
  Lines        6318     6291      -27     
==========================================
- Hits         6157     6101      -56     
- Misses        161      190      +29     
```


| [Impacted Files](https://codecov.io/gh/mwaskom/seaborn/pull/2504?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [seaborn/distributions.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9kaXN0cmlidXRpb25zLnB5) | `96.01% <100.00%> (-0.33%)` | :arrow_down: |
| [seaborn/\_docstrings.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9fZG9jc3RyaW5ncy5weQ==) | `89.18% <0.00%> (-10.82%)` | :arrow_down: |
| [seaborn/\_statistics.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9fc3RhdGlzdGljcy5weQ==) | `98.43% <0.00%> (-1.57%)` | :arrow_down: |
| [seaborn/regression.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9yZWdyZXNzaW9uLnB5) | `96.51% <0.00%> (-1.28%)` | :arrow_down: |
| [seaborn/matrix.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9tYXRyaXgucHk=) | `94.95% <0.00%> (-0.92%)` | :arrow_down: |
| [seaborn/categorical.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9jYXRlZ29yaWNhbC5weQ==) | `98.01% <0.00%> (-0.53%)` | :arrow_down: |
| [seaborn/utils.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi91dGlscy5weQ==) | `94.21% <0.00%> (-0.35%)` | :arrow_down: |
| [seaborn/\_core.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9fY29yZS5weQ==) | `98.47% <0.00%> (-0.15%)` | :arrow_down: |
| [seaborn/axisgrid.py](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree#diff-c2VhYm9ybi9heGlzZ3JpZC5weQ==) | `95.57% <0.00%> (-0.05%)` | :arrow_down: |
| ... and [2 more](https://codecov.io/gh/mwaskom/seaborn/pull/2504/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2504?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/2504?src=pr&el=footer). Last update [ba4bd0f...e60fea9](https://codecov.io/gh/mwaskom/seaborn/pull/2504?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/seaborn/distributions.py b/seaborn/distributions.py
index b227a268..821926f1 100644
--- a/seaborn/distributions.py
+++ b/seaborn/distributions.py
@@ -57,8 +57,10 @@ multiple : {{"layer", "stack", "fill"}}
     """,
     log_scale="""
 log_scale : bool or number, or pair of bools or numbers
-    Set a log scale on the data axis (or axes, with bivariate data) with the
-    given base (default 10), and evaluate the KDE in log space.
+    Set axis scale(s) to log. A single value sets the data axis for univariate
+    distributions and both axes for bivariate distributions. A pair of values
+    sets each axis independently. Numeric values are interpreted as the desired
+    base (default 10). If `False`, defer to the existing Axes scale.
     """,
     legend="""
 legend : bool
@@ -1201,6 +1203,12 @@ class _DistributionPlotter(VectorPlotter):
             if "hue" in self.variables:
                 artist_kws["color"] = self._hue_map(sub_vars["hue"])
 
+            # Return the data variable to the linear domain
+            # This needs an automatic solution; see GH2409
+            if self._log_scaled(self.data_variable):
+                vals = np.power(10, vals)
+                vals[0] = -np.inf
+
             # Work out the orientation of the plot
             if self.data_variable == "x":
                 plot_args = vals, stat
@@ -1277,6 +1285,11 @@ class _DistributionPlotter(VectorPlotter):
         vector = sub_data[var]
         n = len(vector)
 
+        # Return data to linear domain
+        # This needs an automatic solution; see GH2409
+        if self._log_scaled(var):
+            vector = np.power(10, vector)
+
         # We'll always add a single collection with varying colors
         if "hue" in self.variables:
             colors = self._hue_map(sub_data["hue"])


Test patch:
diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py
index f4e9c302..063c0ff1 100644
--- a/seaborn/tests/test_distributions.py
+++ b/seaborn/tests/test_distributions.py
@@ -295,6 +295,20 @@ class TestRugPlot(SharedAxesLevelTests):
         assert ax.get_xlabel() == flat_series.name
         assert not ax.get_ylabel()
 
+    def test_log_scale(self, long_df):
+
+        ax1, ax2 = plt.figure().subplots(2)
+
+        ax2.set_xscale("log")
+
+        rugplot(data=long_df, x="z", ax=ax1)
+        rugplot(data=long_df, x="z", ax=ax2)
+
+        rug1 = np.stack(ax1.collections[0].get_segments())
+        rug2 = np.stack(ax2.collections[0].get_segments())
+
+        assert_array_almost_equal(rug1, rug2)
+
 
 class TestKDEPlotUnivariate(SharedAxesLevelTests):
 
@@ -2056,6 +2070,19 @@ class TestECDFPlotUnivariate(SharedAxesLevelTests):
         with pytest.raises(NotImplementedError, match="Bivariate ECDF plots"):
             ecdfplot(data=long_df, x="x", y="y")
 
+    def test_log_scale(self, long_df):
+
+        ax1, ax2 = plt.figure().subplots(2)
+
+        ecdfplot(data=long_df, x="z", ax=ax1)
+        ecdfplot(data=long_df, x="z", log_scale=True, ax=ax2)
+
+        # Ignore first point, which either -inf (in linear) or 0 (in log)
+        line1 = ax1.lines[0].get_xydata()[1:]
+        line2 = ax2.lines[0].get_xydata()[1:]
+
+        assert_array_almost_equal(line1, line2)
+
 
 class TestDisPlot: