Repository: holoviz/holoviews
Pull request #6543 (2025-03-17 14:46:04)

fix: multi_y give weird error if single element
Fixes https://github.com/holoviz/holoviews/issues/6322

If `self.subplots` is falsy we just treat it as a "normal". 

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/holoviz/holoviews/pull/6543?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 88.79%. Comparing base [(`99d3528`)](https://app.codecov.io/gh/holoviz/holoviews/commit/99d3528270f9ad79caa75df966ebfac75df8ef00?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz) to head [(`3a2d737`)](https://app.codecov.io/gh/holoviz/holoviews/commit/3a2d737b52674d63b622b5daabab3a155d3fc69e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz).
> Report is 1 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #6543      +/-   ##
==========================================
- Coverage   88.79%   88.79%   -0.01%     
==========================================
  Files         323      323              
  Lines       68960    68963       +3     
==========================================
+ Hits        61236    61237       +1     
- Misses       7724     7726       +2     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/holoviz/holoviews/pull/6543?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz).

<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4ae094661..cd45cce8c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -17,12 +17,12 @@ repos:
       - id: check-json
       - id: detect-private-key
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.10.0
+    rev: v0.11.0
     hooks:
       - id: ruff
         exclude: \.ipynb$
   - repo: https://github.com/hoxbro/clean_notebook
-    rev: v0.1.15
+    rev: v0.1.17
     hooks:
       - id: clean-notebook
         args: [--strip-trailing-newlines]
diff --git a/holoviews/element/stats.py b/holoviews/element/stats.py
index ac24b118d..83be95996 100644
--- a/holoviews/element/stats.py
+++ b/holoviews/element/stats.py
@@ -30,11 +30,13 @@ class StatisticsElement(Dataset, Element2D):
         params.update(dict(kdims=kdims, vdims=[], _validate_vdims=False))
         super().__init__(data, **params)
         if not vdims:
-            self.vdims = [Dimension('Density')]
+            with param.edit_constant(self):
+                self.vdims = [Dimension('Density')]
         elif len(vdims) > 1:
             raise ValueError(f"{type(self).__name__} expects at most one vdim.")
         else:
-            self.vdims = process_dimensions(None, vdims)['vdims']
+            with param.edit_constant(self):
+                self.vdims = process_dimensions(None, vdims)['vdims']
 
     @property
     def dataset(self):
diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py
index 53388315e..b7376ac05 100644
--- a/holoviews/plotting/bokeh/element.py
+++ b/holoviews/plotting/bokeh/element.py
@@ -919,7 +919,7 @@ class ElementPlot(BokehPlot, GenericElementPlot):
 
         axis_specs = {'x': {}, 'y': {}}
         axis_specs['x']['x'] = (*self._axis_props(plots, subplots, element, ranges, pos=0), self.xaxis, {})
-        if self.multi_y:
+        if self.multi_y and subplots:
             if not BOKEH_GE_3_2_0:
                 self.param.warning('Independent axis zooming for multi_y=True only supported for Bokeh >=3.2')
             yaxes, extra_axis_specs = self._create_extra_axes(plots, subplots, element, ranges)
diff --git a/holoviews/plotting/mpl/chart.py b/holoviews/plotting/mpl/chart.py
index 915ee6cff..7562b1cc3 100644
--- a/holoviews/plotting/mpl/chart.py
+++ b/holoviews/plotting/mpl/chart.py
@@ -369,6 +369,8 @@ class HistogramPlot(ColorbarPlot):
         xlim = hist.range(0)
         ylim = hist.range(1)
         is_datetime = isdatetime(edges)
+        if hasattr(edges, "compute"):
+            edges = edges.compute()
         if is_datetime:
             edges = np.array([dt64_to_dt(e) if isinstance(e, np.datetime64) else e for e in edges])
             edges = date2num(edges)
diff --git a/pixi.toml b/pixi.toml
index 5479d1d5a..60bf033ce 100644
--- a/pixi.toml
+++ b/pixi.toml
@@ -171,7 +171,7 @@ nbval = "*"
 channels = ["microsoft"]
 
 [feature.test-ui.dependencies]
-playwright = { version = "*", channel = "microsoft" }
+playwright = { version = "!=1.51.0", channel = "microsoft" } # https://github.com/microsoft/playwright-python/issues/2791
 pytest-playwright = { version = "*", channel = "microsoft" }
 
 [feature.test-ui.tasks]


Test patch:
diff --git a/holoviews/tests/operation/test_operation.py b/holoviews/tests/operation/test_operation.py
index 01fd131f6..ff20fb4ec 100644
--- a/holoviews/tests/operation/test_operation.py
+++ b/holoviews/tests/operation/test_operation.py
@@ -593,6 +593,25 @@ class OperationTests(ComparisonTestCase):
         hist = Histogram(([1.,  4., 7.5], [0, 3, 6, 9]), vdims=['y'])
         self.assertEqual(op_hist, hist)
 
+    @pytest.mark.usefixtures("mpl_backend")
+    def test_histogram_dask_array_mpl(self):
+        # Regression test for https://github.com/holoviz/holoviews/issues/5111
+        dd = pytest.importorskip("dask.dataframe")
+
+        data = {
+            "carrier": ["A", "A", "A", "A", "B", "B", "B", "B", "B"],
+            "depdelay": [127.0, 3.0, -3.0, 19.0, 264.0, -6.0, 1.0, 2.0, 83.0],
+        }
+        flights = dd.from_pandas(pd.DataFrame(data), npartitions=2)
+
+        by = "carrier"
+        ds = Dataset(flights, by)
+        ds_grouped = ds.groupby(by)
+        hists = histogram(ds_grouped, dimension="depdelay")
+
+        # Should not error
+        renderer("matplotlib").get_plot(hists)
+
     def test_interpolate_curve_pre(self):
         interpolated = interpolate_curve(Curve([0, 0.5, 1]), interpolation='steps-pre')
         curve = Curve([(0, 0), (0, 0.5), (1, 0.5), (1, 1), (2, 1)])
diff --git a/holoviews/tests/plotting/bokeh/test_multiaxis.py b/holoviews/tests/plotting/bokeh/test_multiaxis.py
index 540351b31..0024d12e6 100644
--- a/holoviews/tests/plotting/bokeh/test_multiaxis.py
+++ b/holoviews/tests/plotting/bokeh/test_multiaxis.py
@@ -306,3 +306,10 @@ class TestCurveTwinAxes(LoggingComparisonTestCase, TestBokehPlot):
         assert plot.state.yaxis[0].axis_label_text_font_size == '15pt'
         assert plot.state.yaxis[1].axis_label == 'A'
         assert plot.state.yaxis[1].axis_label_text_font_size == '13pt'
+
+    def test_multi_y_on_curve(self):
+        # Test for https://github.com/holoviz/holoviews/issues/6322
+        overlay = Curve(range(10), vdims='A').opts(multi_y=True)
+
+        # Should not error
+        bokeh_renderer.get_plot(overlay)