Holomap with Multiple Nested Plots

I need to Show 4 different Line Charts for each direction and for each day of the week.

Here is the idea:

I’m using * operator to merge curves in a single plot and + operator to create plots side by side.

But Now when I wrap those plots into holomap for each day. it throws an exception.

WARNING:param.Warning: Nesting Layouts within a HoloMap makes it difficult to access your data 
or control how it appears; we recommend calling .collate() on the HoloMap in order to follow the recommended nesting structure shown in the Composing Data user guide (https://goo.gl/2YS8LJ)
ERROR:root:'HoloMap' object has no attribute 'set_path'
concurrent.futures.process._RemoteTraceback: 
"""
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\concurrent\futures\process.py", line 239, in _process_worker
    r = call_item.fn(*call_item.args, **call_item.kwargs)
  File "testing2.py", line 217, in create_approach_plot
    hv.save(plot, outputFolder + 'testing_{0}.html'.format(variable_col))
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\util\__init__.py", line 799, in save
    return renderer_obj.save(obj, filename, fmt=fmt, resources=resources)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\plotting\renderer.py", line 557, in save
    plot.layout.save(basename, embed=True, resources=resources)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\viewable.py", line 684, in save
    embed_json, json_prefix, save_path, load_path)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\io\save.py", line 130, in save
    model = panel.get_root(doc, comm)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\viewable.py", line 642, in get_root
    root = self._get_model(doc, comm=comm)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\layout.py", line 120, in _get_model
    objects = self._get_objects(model, [], doc, root, comm)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\layout.py", line 110, in _get_objects
    child = pane._get_model(doc, root, model, comm)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\pane\holoviews.py", line 227, in _get_model
    plot = self._render(doc, comm, root)
  File "C:\ProgramData\Anaconda3\lib\site-packages\panel\pane\holoviews.py", line 286, in _render
    return renderer.get_plot(self.object, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\plotting\bokeh\renderer.py", line 73, in get_plot
    plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\plotting\renderer.py", line 220, in get_plot
    obj = collate(obj)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\plotting\util.py", line 75, in collate
    return obj.collate()
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\core\spaces.py", line 349, in collate
    drop_constant=drop_constant)()
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\core\element.py", line 481, in __call__
    accumulator.update(component)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\core\tree.py", line 103, in update
    self[identifier] = element
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\core\tree.py", line 175, in __setitem__
    self.set_path(identifier, val)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\core\tree.py", line 122, in set_path
    attrtree.set_path(path[1:], val)
  File "C:\ProgramData\Anaconda3\lib\site-packages\holoviews\core\tree.py", line 122, in set_path
    attrtree.set_path(path[1:], val)
AttributeError: 'HoloMap' object has no attribute 'set_path'
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "testing2.py", line 288, in <module>
    data = future.result()
  File "C:\ProgramData\Anaconda3\lib\concurrent\futures\_base.py", line 428, in result
    return self.__get_result()
  File "C:\ProgramData\Anaconda3\lib\concurrent\futures\_base.py", line 384, in __get_result
    raise self._exception
AttributeError: 'HoloMap' object has no attribute 'set_path'

Thanks for the issue but I’d really need a minimal reproducible example to provide help here.

@philippjfr Thanks for your response,

I shared my code on GitHub, I was facing the shared_axes issue, It was fixed with your suggestion. Thanks for that.

Here is my code, Now I want these 4 charts to be wrapped into a holomap for each day.

def get_line_chart(plot_data, agg, agg_by, variable_col, direction):
    curves_list = []
    xaix = sorted(plot_data[agg].dropna().drop_duplicates())
    
    for turnDirection, data in plot_data.groupby([variable_col]):
        curve = hv.Curve((data[agg], data[agg_by]), name=str(turnDirection), label=str(turnDirection)) \
            .opts(xlabel=agg, xrotation=90, ylabel=agg_by)
        curves_list.append(curve)

    return hv.Overlay(curves_list).opts(title=direction, width=700)

def create_plot(df1, maxIntersections, agg_present, agg_by, variable_col, outputFolder):

    plots_dic = OrderedDict()

    for agg, data in df1.groupby(['intersection', 'dow']):
        plots = []
        for direction in ['East', 'West',  'North', 'South']:
            filtered_data = data[data["inboundDir"] == direction]
            plots.append(get_line_chart(filtered_data, agg_present[1], agg_by, variable_col, direction))
            plots_dic[(agg[0], dow_dict[agg[1]])] = hv.Layout(plots).opts(shared_axes=False).cols(2)

    plot = hv.HoloMap(plots_dic, kdims=['Intersection', 'Day of Week'], sort=False)
    plot.opts(height=500, width=500)
    plot.opts(title="Directions Plot", fontsize={'title': 13})
    hv.save(plot, outputFolder + 'WorstIntersectionsAreaPlot{0}.html'.format(variable_col))

@philippjfr I’m stuck on this, can you please help? Also, the above code is adding directions multiple time, 6 plots instead of 4:

For the sample of data, I’m able to create a selector. But with full data, same error as mentioned above.
On the sample data 6 plots but no exception:

Debugging:

print(len(plots)) # Always prints 4, still 6 plots in output. 
plots_dic[(agg[0], dow_dict[agg[1]])] = hv.Layout(plots).opts(shared_axes=False).cols(2)

@zia_kayani I still don’t have a fully reproducible example here, so it’s really hard to provide a solution. So all I can provide are some notes:

plots_dic[(agg[0], dow_dict[agg[1]])] = hv.Layout(plots).opts(shared_axes=False).cols(2)

You should generally avoid nesting Layouts inside HoloMaps. In your particular case doing it this way means that plot.opts(height=500, width=500) does nothing. The real issue here seems to be that your indentation is off:

    plots = []
    for direction in ['East', 'West',  'North', 'South']:
        filtered_data = data[data["inboundDir"] == direction]
        plots.append(get_line_chart(filtered_data, agg_present[1], agg_by, variable_col, direction))
        plots_dic[(agg[0], dow_dict[agg[1]])] = hv.Layout(plots).opts(shared_axes=False).cols(2)

Here you’re adding hv.Layouts(plots) to the plots_dic a bunch of times. I suspect you meant:

    plots = []
    for direction in ['East', 'West',  'North', 'South']:
        filtered_data = data[data["inboundDir"] == direction]
        plots.append(get_line_chart(filtered_data, agg_present[1], agg_by, variable_col, direction))
    plots_dic[(agg[0], dow_dict[agg[1]])] = hv.Layout(plots).opts(shared_axes=False).cols(2)

@philippjfr I really appreciate your response and precious time.

The indentation issue is I guess occur while pasting the code here. I’m not adding plots again and again.

Give me a day, I will share the data along with minimal end to end example. so that you can reproduce the issue.

Thanks again, I really was struggling in this.