1
votes

I have a hv.NdOverlay plot of multiple holoviews.Curve objects. The Curve objects belong to a group (in this case either group 'A' or group 'B'). How do I set up the hv.NdOverlay plot to show a legend which shows the two groups?

Code example (holoviews version: 1.13.4):

import holoviews as hv
import numpy as np
from datetime import datetime
from holoviews import opts

hv.extension('bokeh')

x_start = [0, 100, 100, 0, 120, 200]
x_end = [220, 340, 280, 120, 290, 400]
date = [datetime(2020, 2, 10, 0, 0, 0), datetime(2018, 5, 22, 0, 0, 0),
        datetime(2012, 7, 8, 0, 0, 0), datetime(1999, 12, 28, 0, 0, 0), 
        datetime(2004, 3, 21, 0, 0, 0), datetime(1992, 11, 23, 0, 0, 0)]
group = ['A', 'A', 'B', 'A', 'A', 'B']

curves_dict = dict()
for key in range(len(x_start)):
    curves_dict[key] = hv.Curve(((x_start[key], x_end[key]),
                                 (np.datetime64(date[key]), np.datetime64(date[key]))),
                                'X', 'Year',
                                group=group[key])

curves_ndoverlay_all = hv.NdOverlay(curves_dict)
curves_ndoverlay_all.opts(
    opts.NdOverlay(show_grid=True, height=300, responsive=True, align='center'),
    opts.Curve('A', color='red'),
    opts.Curve('B', color='green'))

What I get is this: Line plo, 2 groups

What I would like to get is a legend with 2 entries, one displaying a red line followed by the letter 'A' and the other one displaying a green line followed by the letter 'B'. It looks like holoviews.NdOverlay is pulling the information for the legend from the keys of the curves_dict. But the keys must be unique. So it looks like this won't work for my intended plot. Is there a different way to set up the holoviews.NdOverlay so that I get the legend I described above?

1
Hi! Keep in mind that there are tons of python developers out there, and it helps them find your question if you have the python tag in your python based question.Ann Zen

1 Answers

0
votes

Is this the result you are looking for?

Legend with two items

This is the code I was using to create it:

import holoviews as hv
import numpy as np
from datetime import datetime
from holoviews import opts

hv.extension('bokeh')

x_start = [0, 100, 100, 0, 120, 200]
x_end = [220, 340, 280, 120, 290, 400]
date = [datetime(2020, 2, 10, 0, 0, 0), datetime(2018, 5, 22, 0, 0, 0),
        datetime(2012, 7, 8, 0, 0, 0), datetime(1999, 12, 28, 0, 0, 0), 
        datetime(2004, 3, 21, 0, 0, 0), datetime(1992, 11, 23, 0, 0, 0)]
group = ['A', 'A', 'B', 'A', 'A', 'B']

def fig(key):
    return hv.Curve(((x_start[key], x_end[key]), (np.datetime64(date[key]), np.datetime64(date[key]))),
        'X', 'Year',
        group=group[key],
        label=group[key]
        )

for i in range(len(group)):
    if i == 0:
        f = fig(i)
    else:
        f *= fig(i)
        
f.opts(opts.Curve(show_grid=True, height=300, responsive=True, align='center'),    
       opts.Curve('A', color='red'),
       opts.Curve('B', color='green'))

There are two things different to your approach. I made use of the label parameter of the hv.Curve() and I don't use NdOverlay anymore.