Repository: holoviz/holoviews
Pull request #6461 (2024-11-29 09:07:32)

docs: Improve LSP information for `extension`
Before:
![image](https://github.com/user-attachments/assets/7d403e68-605c-4d87-9097-a1e94e6fabc7)

After:
![ Screenshot 2024-11-29 10 05 03](https://github.com/user-attachments/assets/5b0f60cd-5299-4c70-a70a-06cdc2055329)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/holoviz/holoviews/pull/6461?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz) Report
Attention: Patch coverage is `66.66667%` with `1 line` in your changes missing coverage. Please review.
> Project coverage is 88.49%. Comparing base [(`93040aa`)](https://app.codecov.io/gh/holoviz/holoviews/commit/93040aa71a19f01dfaf1458772239a49ea5b20cf?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz) to head [(`638ed71`)](https://app.codecov.io/gh/holoviz/holoviews/commit/638ed7175d2b047a2005ad1b3d302786371903af?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.

| [Files with missing lines](https://app.codecov.io/gh/holoviz/holoviews/pull/6461?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz) | Patch % | Lines |
|---|---|---|
| [holoviews/\_\_init\_\_.py](https://app.codecov.io/gh/holoviz/holoviews/pull/6461?src=pr&el=tree&filepath=holoviews%2F__init__.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz#diff-aG9sb3ZpZXdzL19faW5pdF9fLnB5) | 66.66% | [1 Missing :warning: ](https://app.codecov.io/gh/holoviz/holoviews/pull/6461?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=holoviz) |

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


```diff
@@            Coverage Diff             @@
##             main    #6461      +/-   ##
==========================================
- Coverage   88.50%   88.49%   -0.01%     
==========================================
  Files         323      323              
  Lines       68631    68634       +3     
==========================================
  Hits        60741    60741              
- Misses       7890     7893       +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/holoviz/holoviews/pull/6461?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).


Patch:
diff --git a/holoviews/__init__.py b/holoviews/__init__.py
index a8b3f5868..2dd7f5249 100644
--- a/holoviews/__init__.py
+++ b/holoviews/__init__.py
@@ -76,6 +76,7 @@ To report issues go to https://github.com/holoviz/holoviews.
 import builtins
 import os
 import sys
+from typing import TYPE_CHECKING
 
 import param
 
@@ -132,6 +133,11 @@ if '_pyodide' in sys.modules:
         extension = pyodide_extension
     del pyodide_extension, in_jupyterlite
 
+
+if TYPE_CHECKING:
+    # Adding this here to have better docstring in LSP
+    from .util import extension
+
 # A single holoviews.rc file may be executed if found.
 for rcfile in [os.environ.get("HOLOVIEWSRC", ''),
                os.path.abspath(os.path.join(os.path.split(__file__)[0],
diff --git a/holoviews/plotting/bokeh/raster.py b/holoviews/plotting/bokeh/raster.py
index 056e49e5c..99f524752 100644
--- a/holoviews/plotting/bokeh/raster.py
+++ b/holoviews/plotting/bokeh/raster.py
@@ -363,7 +363,7 @@ class QuadMeshPlot(ColorbarPlot):
 
         if self.invert_axes: x, y = y, x
         cmapper = self._get_colormapper(z, element, ranges, style)
-        cmapper = {'field': z.name, 'transform': cmapper}
+        cmapper = {'field': dimension_sanitizer(z.name), 'transform': cmapper}
 
         irregular = (element.interface.irregular(element, x) or
                      element.interface.irregular(element, y))
@@ -405,11 +405,10 @@ class QuadMeshPlot(ColorbarPlot):
                     mask.append(False)
             mask = np.array(mask)
 
-            data = {'xs': XS, 'ys': YS, z.name: zvals[mask]}
+            data = {'xs': XS, 'ys': YS, dimension_sanitizer(z.name): zvals[mask]}
             if 'hover' in self.handles:
                 if not self.static_source:
-                    hover_data = self._collect_hover_data(
-                            element, mask, irregular=True)
+                    hover_data = self._collect_hover_data(element, mask, irregular=True)
                 hover_data[x] = np.array(xc)
                 hover_data[y] = np.array(yc)
         else:
diff --git a/holoviews/util/__init__.py b/holoviews/util/__init__.py
index 30cadf8b5..f0e7e1251 100644
--- a/holoviews/util/__init__.py
+++ b/holoviews/util/__init__.py
@@ -659,6 +659,20 @@ class extension(_pyviz_extension):
     Helper utility used to load holoviews extensions. These can be
     plotting extensions, element extensions or anything else that can be
     registered to work with HoloViews.
+
+    The plotting extension is the most commonly used and is
+    used to select the plotting backend. The plotting extension can be
+    loaded using the backend name, e.g. 'bokeh', 'matplotlib' or 'plotly'.
+
+    Examples
+    --------
+    Activate the bokeh plotting extension:
+
+    ```python
+    import holoviews as hv
+    hv.extension("bokeh")
+    ```
+
     """
 
     # Mapping between backend name and module name


Test patch:
diff --git a/holoviews/tests/plotting/bokeh/test_quadmeshplot.py b/holoviews/tests/plotting/bokeh/test_quadmeshplot.py
index 81b9a467d..7e59e2b2c 100644
--- a/holoviews/tests/plotting/bokeh/test_quadmeshplot.py
+++ b/holoviews/tests/plotting/bokeh/test_quadmeshplot.py
@@ -55,6 +55,33 @@ class TestQuadMeshPlot(TestBokehPlot):
         source = plot.handles['source']
         self.assertEqual(source.data['z'], flattened)
 
+    def test_quadmesh_non_sanitized_name(self):
+        # https://github.com/holoviz/holoviews/issues/6460
+        xs = [0, 1, 2]
+        ys = [2, 1, 0]
+        data = np.array([[0,1,2], [3,4,5], [6,7,8]])
+        qmesh = QuadMesh((xs, ys, data), vdims="z (x,y)")
+        plot = bokeh_renderer.get_plot(qmesh)
+        source = plot.handles['source']
+
+        flattened = np.array([6, 3, 0, 7, 4, 1, 8, 5, 2])
+        sanitized_name = 'z_left_parenthesis_x_comma_y_right_parenthesis'
+        np.testing.assert_equal(source.data[sanitized_name], flattened)
+
+    def test_quadmesh_non_sanitized_name_grid(self):
+        # https://github.com/holoviz/holoviews/issues/6460
+        xs = [0, 1, 2]
+        ys = [2, 1, 0]
+        data = np.array([[0,1,2], [3,4,5], [6,7,8]])
+        XX, YY = np.meshgrid(xs, ys)
+        qmesh = QuadMesh((XX, YY, data), vdims="z (x,y)")
+        plot = bokeh_renderer.get_plot(qmesh)
+        source = plot.handles['source']
+
+        flattened = data.flatten()
+        sanitized_name = 'z_left_parenthesis_x_comma_y_right_parenthesis'
+        np.testing.assert_equal(source.data[sanitized_name], flattened)
+
     def test_quadmesh_nodata_uint(self):
         xs = [0, 1, 2]
         ys = [2, 1, 0]