hvPlot: how to render multi-index as nested x-axis?

I have a dataframe on which I operate a groupby, let say:

df = df.groupby([df.index.weekday, df.index.hour]).mean()

        Quantity
day  hour           
WE  0     12
    1     13
    2     14.5
    3     17
    4     22
           Quantity
day hour           
WE  0     5
    1     9.5
    2     17
    3     35
    4     14

When plotting this dataframe, I would expect a graph with nested categories as per this bokeh exemple but holoviews ignore the index and just display number from 1 to 48.

Help would be welcome

1 Like

Hi @akasolace

Welcome to the community. Could you please provide a minimum, reproducible example to try to start from? This would make it much easier to try to help. Thanks.

The solution might be to reset_index without dropping. Then you can use the day and hour as kdims for HoloViews.

import holoviews as hv
import pandas as pd

data=pd.DataFrame([
    ("Monday", 0, 1.0),
    ("Monday", 1, 2.0),
    ("Monday", 2, 3.0),
    ("Monday", 3, 4.0),
    ("Tuesday", 0, 1.0),
    ("Tuesday", 1, 2.0),
    ("Tuesday", 2, 3.0),
    ("Tuesday", 3, 4.0),
],
 columns=["day", "hour", "value"])

plot = hv.Bars(data, kdims=["day", "hour"], vdims="value")
plot.opts(height=500, cmap=["#0072B5", "#3D4756", "#A1ACBD", "#E782A5"], tools=["hover"])

import panel as pn
pn.extension(sizing_mode="stretch_width", template="fast")
pn.state.template.param.update(site="Awesome Panel", title="Plotting a multi index dataframe using HoloViews")
pn.panel(plot).servable()
2 Likes

Thank you @Marc,
This solution is indeed working, may I ask you if there is a possibility to achieve the same using hvplot? I tried to pass kdims to df.hvplot.bars but the keyword can’t be passed ?
I am asking because the rest of my panel app is using hvplot and so all my graph have nice hover information when using the mouse on the graph.
Thank you again for your help !!

Hi @akasolace,

Perhaps the following, seems to be exactly much the same but with hvplot though I noted with @Marc I get hover information. I attempted to use the groupby but for whatever reason it wasn’t jigging for myself, maybe because it needed like a sum function or something but I haven’t explored further so I gave the dataframe a multi index with pandas and hvplot seems to work out the box. Hope it helps.

import hvplot
import pandas as pd
import hvplot.pandas
import panel as pn

pn.extension()

data=pd.DataFrame([
    ("Monday", 0, 1.0),
    ("Monday", 1, 2.0),
    ("Monday", 2, 3.0),
    ("Monday", 3, 4.0),
    ("Tuesday", 0, 1.0),
    ("Tuesday", 1, 2.0),
    ("Tuesday", 2, 3.0),
    ("Tuesday", 3, 4.0),
],
 columns=["day", "hour", "value"])

#setup multi index with pandas as couldn't make groupby function work but this seems to do the trick
x = data.set_index(['day', 'hour'])

plot = x.hvplot.bar()
plot.opts(height=500, cmap=["#0072B5", "#3D4756", "#A1ACBD", "#E782A5"], tools=["hover"])

pn.panel(plot).show()

Cheers, Carl.

@Carl, I am confused, I tried that many times and it did not work, but now just tried it again and it works as expected !
Thank you

2 Likes