From a02b6bf97bc3c66060f78bcc6704627d5638632d Mon Sep 17 00:00:00 2001 From: Michael Waskom Date: Fri, 14 Oct 2022 21:41:27 -0400 Subject: [PATCH] Fix Plot with no variance in orient dimension (#3084) * Fix Plot with no variance in orient dimension * Update release notes * Update test with new correct behavior --- doc/whatsnew/v0.12.1.rst | 2 ++ seaborn/_core/scales.py | 7 ++++++- tests/_core/test_plot.py | 8 ++++++++ tests/_marks/test_line.py | 5 +++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/doc/whatsnew/v0.12.1.rst b/doc/whatsnew/v0.12.1.rst index f655539268..5db8f8644a 100644 --- a/doc/whatsnew/v0.12.1.rst +++ b/doc/whatsnew/v0.12.1.rst @@ -22,6 +22,8 @@ v0.12.1 (Unreleased) - |Fix| Made :class:`objects.PolyFit` robust to missing data (:pr:`3010`). +- |Fix| Fixed a bug in :class:`objects.Plot` that occurred when the orient coordinate data had zero variance (:pr:`3084`). + - |Fix| Fixed a regression in :func:`kdeplot` where passing `cmap` for an unfilled bivariate plot would raise an exception (:pr:`3065`). - |Fix| Addressed a performance regression in :func:`lineplot` with a large number of unique x values (:pr:`3081`). diff --git a/seaborn/_core/scales.py b/seaborn/_core/scales.py index bbd71ec1b5..98f3f00363 100644 --- a/seaborn/_core/scales.py +++ b/seaborn/_core/scales.py @@ -94,7 +94,12 @@ def set_default_locators_and_formatters(self, axis): return InternalScale(name, (forward, inverse)) def _spacing(self, x: Series) -> float: - return self._spacer(x) + space = self._spacer(x) + if np.isnan(space): + # This happens when there is no variance in the orient coordinate data + # Not exactly clear what the right default is, but 1 seems reasonable? + return 1 + return space def _setup( self, data: Series, prop: Property, axis: Axis | None = None, diff --git a/tests/_core/test_plot.py b/tests/_core/test_plot.py index e855aef9e6..85ab6d8165 100644 --- a/tests/_core/test_plot.py +++ b/tests/_core/test_plot.py @@ -683,6 +683,14 @@ def test_empty(self): Plot().plot() assert m.n_splits == 0 + def test_no_orient_variance(self): + + x, y = [0, 0], [1, 2] + m = MockMark() + Plot(x, y).add(m).plot() + assert_array_equal(m.passed_data[0]["x"], x) + assert_array_equal(m.passed_data[0]["y"], y) + def test_single_split_single_layer(self, long_df): m = MockMark() diff --git a/tests/_marks/test_line.py b/tests/_marks/test_line.py index d6849fce06..1339b85945 100644 --- a/tests/_marks/test_line.py +++ b/tests/_marks/test_line.py @@ -253,8 +253,9 @@ def test_single_orient_value(self): y = [1, 2, 3] p = Plot(x, y).add(Lines()).plot() lines, = p._figure.axes[0].collections - paths, = lines.get_paths() - assert paths.vertices.shape == (0, 2) + verts = lines.get_paths()[0].vertices.T + assert_array_equal(verts[0], x) + assert_array_equal(verts[1], y) class TestRange: