hvplot
hvplot copied to clipboard
color not working for bar plot with Plotly backend
I would expect the color
argument to work the same for the Bokeh and Plotly plotting backends when plotting a bar
plot. But they don't.
import pandas as pd
import hvplot.pandas # noqa
hvplot.extension("bokeh")
pd.DataFrame({
"framework": ["hvPlot", "HoloViews", "Panel"],
"stars": [700, 2400, 2600]
}).hvplot.bar(x="framework", y="stars", color="gold", title="Bar Plot of Github Stars as of March 2023", ylabel="⭐")
hvplot.extension("plotly")
pd.DataFrame({
"framework": ["hvPlot", "HoloViews", "Panel"],
"stars": [700, 2400, 2600]
}).hvplot.bar(x="framework", y="stars", color="gold", title="Bar Plot of Github Stars as of March 2023", ylabel="⭐")
If you try to use a list of colors it raises an exception
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In [9], line 2
1 hvplot.extension("plotly")
----> 2 autompg_wide.hvplot.bar(y=['Asia', 'Europe', 'North America'], width=1000, ylabel="mpg", color=["#ba2649", "#ffa7ca", "#1a6b54"], rot=90)
File c:\repos\private\hvplot\hvplot\plotting\core.py:1046, in hvPlotTabular.bar(self, x, y, **kwds)
959 def bar(self, x=None, y=None, **kwds):
960 """
961 A vertical bar plot
962
(...)
1044 - Wiki: https://en.wikipedia.org/wiki/Bar_chart
1045 """
-> 1046 return self(x, y, kind="bar", **kwds)
File c:\repos\private\hvplot\hvplot\plotting\core.py:92, in hvPlotBase.__call__(self, x, y, kind, **kwds)
89 plot = self._get_converter(x, y, kind, **kwds)(kind, x, y)
90 return pn.panel(plot, **panel_dict)
---> 92 return self._get_converter(x, y, kind, **kwds)(kind, x, y)
File c:\repos\private\hvplot\hvplot\converter.py:1252, in HoloViewsConverter.__call__(self, kind, x, y)
1250 if not (self.datashade or self.rasterize):
1251 layers = self._apply_layers(obj)
-> 1252 layers = _transfer_opts_cur_backend(layers)
1253 return layers
1254 try:
File c:\repos\private\hvplot\hvplot\backend_transforms.py:88, in _transfer_opts_cur_backend(element)
86 def _transfer_opts_cur_backend(element):
87 if Store.current_backend != 'bokeh':
---> 88 element = element.apply(_transfer_opts, backend=Store.current_backend)
89 return element
File c:\repos\private\tmp\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 c:\repos\private\tmp\holoviews\holoviews\core\accessors.py:202, in Apply.__call__(self, apply_function, streams, link_inputs, link_dataset, dynamic, per_element, **kwargs)
200 if hasattr(apply_function, 'dynamic'):
201 inner_kwargs['dynamic'] = False
--> 202 new_obj = apply_function(self._obj, **inner_kwargs)
203 if (link_dataset and isinstance(self._obj, Dataset) and
204 isinstance(new_obj, Dataset) and new_obj._dataset is None):
205 new_obj._dataset = self._obj.dataset
File c:\repos\private\hvplot\hvplot\backend_transforms.py:52, in _transfer_opts(element, backend)
50 continue
51 elif transform:
---> 52 opt, val = transform(opt, val)
53 if val is UNSET:
54 continue
File c:\repos\private\hvplot\hvplot\backend_transforms.py:314, in <lambda>(k, v)
287 # Plotly transforms
289 _line_dash_bk_plotly_mapping = {
290 'solid': 'solid',
291 'dashed': 'dash',
(...)
294 'dashdot': 'dashdot',
295 }
297 PLOTLY_TRANSFORMS = {
298 'plot': {
299 'alpha': lambda k, v: ('opacity', v),
300 'min_height': UNSET,
301 'min_width': UNSET,
302 'max_height': UNSET,
303 'max_width': UNSET,
304 'frame_width': UNSET,
305 'frame_height': UNSET,
306 'batched': UNSET,
307 'legend_limit': UNSET,
308 'tools': UNSET,
309 'shared_xaxis': UNSET,
310 'shared_yaxis': UNSET,
311 },
312 'style': {
313 'alpha': lambda k, v: ('opacity', v),
--> 314 'color': lambda k, v: (k, COLOR_ALIASES.get(v, v)),
315 'fill_color': lambda k, v: ('fillcolor', COLOR_ALIASES.get(v, v)),
316 'line_color': lambda k, v: (k, COLOR_ALIASES.get(v, v)),
317 'line_dash': lambda k, v: ('dash', _line_dash_bk_plotly_mapping.get(v, UNSET)),
318 'line_width': lambda k, v: ('line_width', v),
319 'muted_alpha': UNSET,
320 'palette': UNSET,
321 }
322 }
325 BACKEND_TRANSFORMS = dict(
326 matplotlib=MATPLOTLIB_TRANSFORMS,
327 plotly=PLOTLY_TRANSFORMS,
328 )
TypeError: unhashable type: 'list'
If you try to use the values of a column it does not work either.
import pandas as pd
import hvplot.pandas # noqa
hvplot.extension("plotly")
from bokeh.sampledata.autompg import autompg_clean as autompg
autompg.head()
autompg_long_form = autompg.groupby("yr").mean(numeric_only=True).reset_index()
autompg_long_form.head()
autompg_multi_index = autompg.query("yr<=80").groupby(['yr', 'origin']).mean(numeric_only=True)
autompg_multi_index.head()
autompg_wide = autompg_multi_index.reset_index().pivot(index='yr', columns='origin', values='mpg')
autompg_wide.head()
hvplot.extension("bokeh")
autompg_wide.hvplot.bar(y=['Asia', 'Europe', 'North America'], width=1000, ylabel="mpg", color=["#ba2649", "#ffa7ca", "#1a6b54"], rot=90)
hvplot.extension("plotly")
autompg_wide.hvplot.bar(y=['Asia', 'Europe', 'North America'], width=1000, ylabel="mpg", color=["#ba2649", "#ffa7ca", "#1a6b54"], rot=90)
hvplot.extension("bokeh")
autompg_long_form.hvplot.bar(y='mpg', color="weight", colorbar=True, clabel="Weight", cmap="bmy", width=1000)
hvplot.extension("plotly")
autompg_long_form.hvplot.bar(y='mpg', color="weight", colorbar=True, clabel="Weight", cmap="bmy", width=1000)
The issue seems to originate from HoloViews. I've reported the HoloViews bug here https://github.com/holoviz/holoviews/issues/5658
Just got hit by this again