Why won't my HoloViews DynamicMap update in response to changes to parameter values?

Why don’t changes to parameter values using the controls result in updates to the HoloViews DynamicMap in the MWE below?

import numpy as np
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')

def plot_mwe(M, m, V_0, scale_axes): 
    scale_factor = np.sqrt(M/m) if scale_axes else 1

    V_max = V_0
    v_max = V_0*np.sqrt(M/m)    
    if not scale_axes:
        x_lim, y_lim = ( max(V_max,v_max)*1.1, )*2
    else:   
        x_lim, y_lim = ( v_max*1.1,  V_max*1.1 )   
   
    t = np.linspace(0, 2*np.pi, 100)

    return hv.Contours( {'x': v_max*np.cos(t), 'y':  V_max*np.sin(t)} ).options(xlim=(-x_lim, x_lim), ylim=(-y_lim, y_lim))

# This works as expected and responds as expected to changes in parameter values
plot_mwe(M=1, m=5, V_0=20, scale_axes=False).opts(width=400, height=400)

dynamic_mwe = hv.DynamicMap(plot_mwe, kdims=['M', 'm', 'V_0', 'scale_axes'])   

# This results in the expected error message shown in the documentation
dynamic_mwe

# Nothing changes in response to changes in the controls
dynamic_mwe.redim.range(M=(1,50),m=(1,50),V_0=(1,100)).redim.values(scale_axes=[True, False])

This seems to exactly replicate the example in the “Live parameter exploration” section of the “Live Data” documentation but fails to update. What do I need to do to get my DynamicMap to update in response to changes to linked controls?

I think I see what’s going in here. Though pyviz_comms is installed in the repo associated with the kernel running the notebook (via. pip install holoviews[recommended], and doing so automatically enables pyviz_comms for JuyterLab, it only does so for the instance of JupyterLab launched from within that activated repo. For this to work, it is not enough to use the kernel associated with that repo: JupyterLab must be launched from it.

Note that this is one place were the kernel user model kind of breaks (or is at least a bit confusing): Though you can associate a virtual environment with a kernel, and virtual environments are basically defined by the packages installed in them, and installing packages (now) automatically enables their associated Jupyter extensions, things are not fully transitive. Specifically, enabled extensions are not associated with the kernel, but with the enabled virtual environment from which a JupyterLab instance is launched.

1 Like