Search code examples
pythonholoviewshvplot

What's wrong with my vdims in my HoloViews Python code?


display(df_top5_frac.head())

Output

The code below produces an error.

%opts Overlay [width=800 height=600 legend_position='top_right'] Curve

hv.Curve((df_top5_frac['Blocked Driveway'])      , kdims = ['Hour'], vdims = ['Fraction'], label = 'Blocked Driveway') *\
hv.Curve((df_top5_frac['HEAT/HOT WATER'])        , kdims = ['Hour'], vdims = ['Fraction'], label = 'HEAT/HOT WATER') *\
hv.Curve((df_top5_frac['Illegal Parking'])       , kdims = ['Hour'], vdims = ['Fraction'], label = 'Illegal Parking') *\
hv.Curve((df_top5_frac['Street Condition'])      , kdims = ['Hour'], vdims = ['Fraction'], label = 'Street Condition') *\
hv.Curve((df_top5_frac['Street Light Condition']), kdims = ['Hour'], vdims = ['Fraction'], label = 'Street Light Condition')

Here is the error:

enter image description here


Solution

  • Cause of your error:
    The vdim should be the name of the column you want to have on the y-axis, but the column name 'Fraction' doesn't exist, so you get the error.

    Here's a possible solution:
    When you set hour as the index, you could specify: kdim='hour' and vdim='blocked_driveway', but in this case you don't really need them and can leave them out:

    # import libraries
    import numpy as np
    import pandas as pd
    import holoviews as hv
    hv.extension('bokeh')
    
    # create sample data
    data = {'hour': ['00', '01', '02'],
            'blocked_driveway': np.random.uniform(size=3),
            'illegal_parking': np.random.uniform(size=3),
            'street_condition': np.random.uniform(size=3),}
    
    # create dataframe and set hour as index
    df = pd.DataFrame(data).set_index('hour')
    
    # create curves: 
    # in this case the index is automatically taken as kdim
    # and the series variable, e.g. blocked_driveway is taken as vdim
    plot1 = hv.Curve(df['blocked_driveway'], label='blocked_driveway')
    plot2 = hv.Curve(df['illegal_parking'], label='illegal_parking')
    plot3 = hv.Curve(df['street_condition'], label='street_condition')
    
    # put plots together
    (plot1 * plot2 * plot3).opts(legend_position='top', width=600, height=400)
    


    Alternative and shorter solution:
    In this case however I would use library hvplot which is built on top of holoviews.
    It has even easier syntax and you need a lot less code to get the plot you want:

    import hvplot.pandas
    
    # you don't have to set hour as index this time, but you could if you'd want to.
    df.hvplot.line(
        x='hour', 
        y=['blocked_driveway', 
           'illegal_parking',
           'street_condition'],
    )
    


    Resulting plot: multiple curves overlay with hvplot