Repository: mwaskom/seaborn

Issue:
rugplot fails with datetime data
e.g. 

```python
sns.rugplot(x=np.arange("2015-01-01", "2020-01-01", dtype="datetime64[m]"))
```
```python-traceback
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-0cb72350e3e6> in <module>
      1 #sns.rugplot()
----> 2 sns.rugplot(x=np.arange("2015-01-01", "2020-01-01", dtype="datetime64[m]"))

~/code/seaborn/seaborn/_decorators.py in inner_f(*args, **kwargs)
     44             )
     45         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 46         return f(**kwargs)
     47     return inner_f
     48 

~/code/seaborn/seaborn/distributions.py in rugplot(x, height, axis, ax, data, y, hue, palette, hue_order, hue_norm, expand_margins, legend, a, **kwargs)
   2048         return ax
   2049 
-> 2050     p.plot_rug(height, expand_margins, legend, **kwargs)
   2051 
   2052     return ax

~/code/seaborn/seaborn/distributions.py in plot_rug(self, height, expand_margins, legend, **kws)
   1266 
   1267             if "x" in self.variables:
-> 1268                 self._plot_single_rug(sub_data, "x", height, ax, kws)
   1269             if "y" in self.variables:
   1270                 self._plot_single_rug(sub_data, "y", height, ax, kws)

~/code/seaborn/seaborn/distributions.py in _plot_single_rug(self, sub_data, var, height, ax, kws)
   1294 
   1295             trans = tx.blended_transform_factory(ax.transData, ax.transAxes)
-> 1296             xy_pairs = np.column_stack([
   1297                 np.repeat(vector, 2), np.tile([0, height], n)
   1298             ])

<__array_function__ internals> in column_stack(*args, **kwargs)

~/miniconda3/envs/seaborn-py38-latest/lib/python3.8/site-packages/numpy/lib/shape_base.py in column_stack(tup)
    654             arr = array(arr, copy=False, subok=True, ndmin=2).T
    655         arrays.append(arr)
--> 656     return _nx.concatenate(arrays, 1)
    657 
    658 

<__array_function__ internals> in concatenate(*args, **kwargs)

TypeError: invalid type promotion
```

The fix is simple -- use `from_comp_data=True` in `iter_data` (we do this basically everywhere, it should probably be the default. But it's surprising to see!

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

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

```diff
@@            Coverage Diff             @@
##           master    #2458      +/-   ##
==========================================
- Coverage   97.45%   97.12%   -0.34%     
==========================================
  Files          17       17              
  Lines        6290     6290              
==========================================
- Hits         6130     6109      -21     
- Misses        160      181      +21     
```


| [Impacted Files](https://codecov.io/gh/mwaskom/seaborn/pull/2458?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [seaborn/distributions.py](https://codecov.io/gh/mwaskom/seaborn/pull/2458/diff?src=pr&el=tree#diff-c2VhYm9ybi9kaXN0cmlidXRpb25zLnB5) | `96.31% <100.00%> (ø)` | |
| [seaborn/algorithms.py](https://codecov.io/gh/mwaskom/seaborn/pull/2458/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/2458/diff?src=pr&el=tree#diff-c2VhYm9ybi91dGlscy5weQ==) | `91.83% <0.00%> (-2.73%)` | :arrow_down: |
| [seaborn/\_core.py](https://codecov.io/gh/mwaskom/seaborn/pull/2458/diff?src=pr&el=tree#diff-c2VhYm9ybi9fY29yZS5weQ==) | `98.06% <0.00%> (-0.56%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/mwaskom/seaborn/pull/2458?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/2458?src=pr&el=footer). Last update [ba086c2...ab4e6dc](https://codecov.io/gh/mwaskom/seaborn/pull/2458?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 1e688924..96944872 100644
--- a/doc/releases/v0.12.0.txt
+++ b/doc/releases/v0.12.0.txt
@@ -18,6 +18,8 @@ v0.12.0 (Unreleased)
 
 - |Fix| In :func:`lineplot, allowed the `dashes` keyword to set the style of a line without mapping a `style` variable (:pr:`2449`).
 
+- |Fix| In :func:`rugplot`, fixed a bug that prevented the use of datetime data (:pr:`2458`).
+
 - |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`).
diff --git a/seaborn/distributions.py b/seaborn/distributions.py
index 8144e458..95ca6dcf 100644
--- a/seaborn/distributions.py
+++ b/seaborn/distributions.py
@@ -1233,7 +1233,7 @@ class _DistributionPlotter(VectorPlotter):
 
     def plot_rug(self, height, expand_margins, legend, **kws):
 
-        for sub_vars, sub_data, in self.iter_data():
+        for sub_vars, sub_data, in self.iter_data(from_comp_data=True):
 
             ax = self._get_axes(sub_vars)
 
diff --git a/seaborn/relational.py b/seaborn/relational.py
index 1cba66f7..c9fc15ad 100644
--- a/seaborn/relational.py
+++ b/seaborn/relational.py
@@ -607,7 +607,7 @@ def lineplot(
     palette=None, hue_order=None, hue_norm=None,
     sizes=None, size_order=None, size_norm=None,
     dashes=True, markers=None, style_order=None,
-    units=None, estimator="mean", ci=None, n_boot=1000, seed=None,
+    units=None, estimator="mean", ci="deprecated", n_boot=1000, seed=None,
     sort=True, err_style="band", err_kws=None,
     legend="auto",
     errorbar=("ci", 95),
diff --git a/seaborn/utils.py b/seaborn/utils.py
index 68091b70..6661ceee 100644
--- a/seaborn/utils.py
+++ b/seaborn/utils.py
@@ -715,14 +715,17 @@ def _deprecate_ci(errorbar, ci):
     (and extracted from kwargs) after one cycle.
 
     """
-    if ci is not None:
-        if ci == "sd":
+    if ci != "deprecated":
+        if ci is None:
+            errorbar = None
+        elif ci == "sd":
             errorbar = "sd"
-            msg = "use `errorbar='sd'` for same effect."
         else:
             errorbar = ("ci", ci)
-            msg = f"use `errorbar=('ci', {ci})` for same effect."
-        msg = f"The `ci` parameter is deprecated; {msg}"
+        msg = (
+            "The `ci` parameter is deprecated; "
+            f"use `errorbar={repr(errorbar)}` for same effect."
+        )
         warnings.warn(msg, UserWarning)
 
     return errorbar


Test patch:
diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py
index 84364897..858ac439 100644
--- a/seaborn/tests/test_distributions.py
+++ b/seaborn/tests/test_distributions.py
@@ -196,6 +196,12 @@ class TestRugPlot(SharedAxesLevelTests):
         rugplot(x=long_df["x"])
         self.assert_rug_equal(*ax.collections)
 
+    def test_datetime_data(self, long_df):
+
+        ax = rugplot(data=long_df["t"])
+        vals = np.stack(ax.collections[0].get_segments())[:, 0, 0]
+        assert_array_equal(vals, mpl.dates.date2num(long_df["t"]))
+
     def test_empty_data(self):
 
         ax = rugplot(x=[])
diff --git a/seaborn/tests/test_utils.py b/seaborn/tests/test_utils.py
index 36bf456c..cab8a357 100644
--- a/seaborn/tests/test_utils.py
+++ b/seaborn/tests/test_utils.py
@@ -28,6 +28,7 @@ from ..utils import (
     load_dataset,
     _assign_default_kwargs,
     _draw_figure,
+    _deprecate_ci,
 )
 
 
@@ -458,3 +459,20 @@ def test_draw_figure():
     assert not f.stale
     # ticklabels are not populated until a draw, but this may change
     assert ax.get_xticklabels()[0].get_text() == "a"
+
+
+def test_deprecate_ci():
+
+    msg = "The `ci` parameter is deprecated; use `errorbar="
+
+    with pytest.warns(UserWarning, match=msg + "None"):
+        out = _deprecate_ci(None, None)
+    assert out is None
+
+    with pytest.warns(UserWarning, match=msg + "'sd'"):
+        out = _deprecate_ci(None, "sd")
+    assert out == "sd"
+
+    with pytest.warns(UserWarning, match=msg + r"\('ci', 68\)"):
+        out = _deprecate_ci(None, 68)
+    assert out == ("ci", 68)