holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.42k stars 484 forks source link

HoloMap update delayed only when inside a HoloViews pane #5501

Open paulmaxus opened 10 months ago

paulmaxus commented 10 months ago

Setup and package versions

I am rendering widget and pane inside a notebook (JupyterLab), but the same issue applies to the Panel Preview and when serving the application locally.

panel=1.2.1 jupyterlab=4.0.3 hvplot=0.8.4 holoviews=1.16.2 networkx=3.1

Description and minimal, self-contained example code

I am writing a panel application using JupyterLab. Specifically, I create a HoloMap with a number of hvplot.networkx plots that can be selected by a slider (the number of plots/frames is manageable). The underlying graph is the same, but edge alpha differs to create an effect of increasing edge strength.

The problem I encounter is that while the HoloMap widget updates smoothly when moving the slider, it is quite slow when rendered inside a pane (pn.panel).

On discourse I've uploaded a video with a more complex example: https://discourse.holoviz.org/t/holomap-gets-slow-when-used-inside-a-holoviews-pane/5985

However, the issue can be replicated well with the minimal example code below:

import panel as pn
import hvplot.networkx as hvnx
import networkx as nx
from holoviews import HoloMap

# number of hvplots
n = 20

# attributes for alpha
attributes = {str(i):i/n for i in range(n)}

# create minimal graph
G = nx.Graph()
G.add_edge('a', 'b', **attributes)

# create hvplots
pos = nx.spring_layout(G)
hvplots = {}
for i in attributes:
    nodes = hvnx.draw_networkx_nodes(G, pos)
    edges = hvnx.draw_networkx_edges(G, pos, alpha=i)
    hvplots[int(i)] = nodes * edges

# create HoloMap
hm = HoloMap(hvplots)

Now (in the notebook), I either create the widget as such by executing hm or inside a pane with pn.panel(hm)

Even for such a minimal HoloMap, the update speed difference is quite large.

philippjfr commented 10 months ago

Thanks for reporting, the issue here is that when displaying the HoloViews object directly it internally calls .embed() while otherwise it still triggers the embedding step but then triggers a re-render when you change the widget anyway because the embedded data isn't used.

paulmaxus commented 10 months ago

Thanks @philippjfr My solution for now is to convert it to a DynamicMap using Dynamic(). Much faster.