pythonholoviewspyviz

How to visualize time span with holoviews?


I recently came across holoviews as promising visualization library in python and - as a practice - I wanted to transfer some of my existing code to see how it looks like in hv. I reached a given plot which I am unable to recreate.

I'd like to visualize a timeline or roadmap where the x axis is with type of pd.datetime and the y is categorical. Something like this:

enter image description here

What Element shall I use? How shall I define start and end position for sections?


Solution

  • This sounds like you need a Gantt chart.
    I am using hv.Curve() drawing a line from the starting point in time to the end point in time:

    # import libraries
    from datetime import datetime
    import holoviews as hv
    hv.extension('bokeh')
    
    # drawing a simple line
    line1 = hv.Curve([
        [datetime(2018, 1,  3), 'Event1'],
        [datetime(2018, 1, 31), 'Event1'],
    ])
    
    # creating a dashed line
    line2 = hv.Curve([
        [datetime(2018, 3,  3), 'Event2'],
        [datetime(2018, 3, 30), 'Event2'],
    ]).opts(line_dash='dashed')
    
    # creating a black thicker line
    line3 = hv.Curve([
        [datetime(2018, 7, 15), 'Event2'],
        [datetime(2018, 9, 23), 'Event2'],
    ]).opts(color='black', line_width=10.0)
    
    # add all 3 lines together on 1 plot with the * symbol
    # this creates an overlay
    gantt_chart = (line1 * line2 * line3)
    
    # change xlim and width of the whole chart and add xlabel
    # just making the plot a bit nicer
    gantt_chart.opts(
        width=800, 
        xlim=(datetime(2018, 1, 1), datetime(2018, 12, 31)),
        xlabel='start to stop',
        ylabel='',
    )
    

    As you can see I've also added some options as an example to change the style of the lines and change the range of the x-axis.

    Example code gives you this graph: enter image description here

    Another solution is a more generic way of generating this Gantt plot, which loops over the data and generates a curve for every start/stop point:

    # import libraries
    from datetime import datetime
    import holoviews as hv
    hv.extension('bokeh')
    
    # create sample data
    data = [
        [datetime(2018, 1, 3), datetime(2018, 1, 31), 'Event1'],
        [datetime(2018, 3, 3), datetime(2018, 3, 30), 'Event2'],   
        [datetime(2018, 7, 15), datetime(2018, 9, 23), 'Event2'],
    ]
    
    # loop over data to create a list with a line/curve for every start/stop point
    all_lines_list = [
        hv.Curve([
            [row[0], row[2]],
            [row[1], row[2]],
        ]).opts(color='red') for row in data
    ]
    
    # put all lines in an Overlay plot that can display all lines on 1 plot
    gantt_chart = hv.Overlay(all_lines_list)
    
    # make plot nicer
    gantt_chart.opts(
        show_legend=False,
        width=800,
        xlim=(datetime(2018, 1, 1), datetime(2018, 12, 31)),
        xlabel='start to stop',
        ylabel='',
    )