Repository: holoviz/holoviews

Issue:
Support muted for all plot bokeh elements
First noticed here: https://discourse.holoviz.org/t/mute-one-of-the-multiple-scatter-series/4031/4
Related PR: https://github.com/holoviz/holoviews/pull/4215

Currently, some plots do not support the muted option, which should be the case

``` python
import pandas as pd
import holoviews as hv

hv.extension("bokeh")

def mute_hook(plot, element):
    plot.handles["glyph_renderer"].muted = True


line = hv.Curve((range(10,)), label="Curve").opts(muted=True)
# scat = hv.Scatter((range(10,)), label="Scatter").opts(muted=True)  # Raises ValueError
scat = hv.Scatter((range(10,)), label="Scatter").opts(hooks=[mute_hook])

line * scat
```

![image](https://user-images.githubusercontent.com/19758978/182533184-0da8c447-b657-4f4a-a243-81c81a091a18.png)


``` python-traceback
ValueError                                Traceback (most recent call last)
Input In [20], in <cell line: 1>()
----> 1 scat = hv.Scatter((range(10,)), label="Scatter").opts(muted=True)

File ~/Development/holoviz/holoviews/holoviews/core/accessors.py:45, in AccessorPipelineMeta.pipelined.<locals>.pipelined_call(*args, **kwargs)
     42     inst._obj._in_method = True
     44 try:
---> 45     result = __call__(*args, **kwargs)
     47     if not in_method:
     48         init_op = factory.instance(
     49             output_type=type(inst),
     50             kwargs={'mode': getattr(inst, 'mode', None)},
     51         )

File ~/Development/holoviz/holoviews/holoviews/core/accessors.py:571, in Opts.__call__(self, *args, **kwargs)
    565         msg = ("Calling the .opts method with options broken down by options "
    566                "group (i.e. separate plot, style and norm groups) is deprecated. "
    567                "Use the .options method converting to the simplified format "
    568                "instead or use hv.opts.apply_groups for backward compatibility.")
    569         param.main.param.warning(msg)
--> 571 return self._dispatch_opts( *args, **kwargs)

File ~/Development/holoviz/holoviews/holoviews/core/accessors.py:575, in Opts._dispatch_opts(self, *args, **kwargs)
    573 def _dispatch_opts(self, *args, **kwargs):
    574     if self._mode is None:
--> 575         return self._base_opts(*args, **kwargs)
    576     elif self._mode == 'holomap':
    577         return self._holomap_opts(*args, **kwargs)

File ~/Development/holoviz/holoviews/holoviews/core/accessors.py:654, in Opts._base_opts(self, *args, **kwargs)
    651     return opts.apply_groups(self._obj, **dict(kwargs, **new_kwargs))
    653 kwargs['clone'] = False if clone is None else clone
--> 654 return self._obj.options(*new_args, **kwargs)

File ~/Development/holoviz/holoviews/holoviews/core/data/__init__.py:204, in PipelineMeta.pipelined.<locals>.pipelined_fn(*args, **kwargs)
    201     inst._in_method = True
    203 try:
--> 204     result = method_fn(*args, **kwargs)
    205     if PipelineMeta.disable:
    206         return result

File ~/Development/holoviz/holoviews/holoviews/core/data/__init__.py:1212, in Dataset.options(self, *args, **kwargs)
   1210 @wraps(Dimensioned.options)
   1211 def options(self, *args, **kwargs):
-> 1212     return super(Dataset, self).options(*args, **kwargs)

File ~/Development/holoviz/holoviews/holoviews/core/dimension.py:1280, in Dimensioned.options(self, clone, *args, **kwargs)
   1278     expanded_backends = opts._expand_by_backend(options, backend)
   1279 else:
-> 1280     expanded_backends = [(backend, opts._expand_options(options, backend))]
   1282 obj = self
   1283 for backend, expanded in expanded_backends:

File ~/Development/holoviz/holoviews/holoviews/util/__init__.py:347, in opts._expand_options(cls, options, backend)
    341         else:
    342             valid_options = sorted({
    343                 keyword
    344                 for group_opts in obj_options.groups.values()
    345                 for keyword in group_opts.allowed_keywords
    346             })
--> 347             cls._options_error(opt, objtype, backend, valid_options)
    348 return expanded

File ~/Development/holoviz/holoviews/holoviews/util/__init__.py:390, in opts._options_error(cls, opt, objtype, backend, valid_options)
    387     return
    389 if matches:
--> 390     raise ValueError('Unexpected option %r for %s type '
    391                      'across all extensions. Similar options '
    392                      'for current extension (%r) are: %s.' %
    393                      (opt, objtype, current_backend, matches))
    394 else:
    395     raise ValueError('Unexpected option %r for %s type '
    396                      'across all extensions. No similar options '
    397                      'found.' % (opt, objtype))

ValueError: Unexpected option 'muted' for Scatter type across all extensions. Similar options for current extension ('bokeh') are: ['muted_alpha', 'muted_color'].

```


Discussion:
@droumis This might be a good one for you when you get a chance!

Resolving patch:
diff --git a/holoviews/plotting/bokeh/chart.py b/holoviews/plotting/bokeh/chart.py
--- a/holoviews/plotting/bokeh/chart.py
+++ b/holoviews/plotting/bokeh/chart.py
@@ -62,8 +62,8 @@ class PointPlot(LegendPlot, ColorbarPlot):
 
     selection_display = BokehOverlaySelectionDisplay()
 
-    style_opts = (['cmap', 'palette', 'marker', 'size', 'angle', 'visible'] +
-                  line_properties + fill_properties)
+    style_opts = (['cmap', 'palette', 'marker', 'size', 'angle'] +
+                  base_properties + line_properties + fill_properties)
 
     _plot_methods = dict(single='scatter', batched='scatter')
     _batched_style_opts = line_properties + fill_properties + ['size', 'marker', 'angle']


Test patch: