diff --git a/hvplot/converter.py b/hvplot/converter.py index 9aadbc358..0d225a94a 100644 --- a/hvplot/converter.py +++ b/hvplot/converter.py @@ -76,6 +76,7 @@ process_derived_datetime_pandas, _convert_col_names_to_str, import_datashader, + is_mpl_cmap, ) from .utilities import hvplot_extension @@ -1420,7 +1421,7 @@ def _process_style(self, kwds, plot_opts): valid_opts = [] cmap_opts = ('cmap', 'colormap', 'color_key') - categories = [ + categorical_cmaps = [ 'accent', 'category', 'dark', @@ -1485,7 +1486,13 @@ def _process_style(self, kwds, plot_opts): if 'color' in style_opts: color = style_opts['color'] elif not isinstance(cmap, dict): - if cmap and any(c in cmap for c in categories): + # Checks if any of the categorical cmaps matches cmap; + # uses any() instead of `cmap in categorical_cmaps` to handle reversed colormaps (suffixed with `_r`). + # If cmap is LinearSegmentedColormap, get the name attr, else return the str typed cmap. + if (isinstance(cmap, str) or is_mpl_cmap(cmap)) and any( + categorical_cmap in getattr(cmap, 'name', cmap) + for categorical_cmap in categorical_cmaps + ): color = process_cmap(cmap or self._default_cmaps['categorical'], categorical=True) else: color = cmap diff --git a/hvplot/tests/testcharts.py b/hvplot/tests/testcharts.py index 0067d6444..fead2d0a6 100644 --- a/hvplot/tests/testcharts.py +++ b/hvplot/tests/testcharts.py @@ -606,3 +606,14 @@ def test_table_datetime_index_displayed(self): def test_table_multi_index_displayed(self): raise SkipTest('Dask does not support MultiIndex Dataframes.') + + +def test_cmap_LinearSegmentedColormap(): + # test for https://github.com/holoviz/hvplot/pull/1461 + xr = pytest.importorskip('xarray') + mpl = pytest.importorskip('matplotlib') + import hvplot.xarray # noqa + + data = np.arange(25).reshape(5, 5) + xr_da = xr.DataArray(data) + xr_da.hvplot.image(cmap=mpl.colormaps['viridis']) diff --git a/hvplot/util.py b/hvplot/util.py index e0392e300..db347c608 100644 --- a/hvplot/util.py +++ b/hvplot/util.py @@ -750,3 +750,12 @@ def relabel_redim(hv_obj, relabel_kwargs, redim_kwargs): if redim_kwargs: hv_obj = hv_obj.redim(**redim_kwargs) return hv_obj + + +def is_mpl_cmap(obj): + """Check if the object is a Matplotlib LinearSegmentedColormap.""" + if 'matplotlib' not in sys.modules: + return False + from matplotlib.colors import LinearSegmentedColormap + + return isinstance(obj, LinearSegmentedColormap)