Panel | Tutorial 4 APIs

2023/02/16 05:30 AM posted in  Coding Notes   comments
Tags:  #Panel

  1. Interact functions: Auto-generates a full UI (including widgets) given a function
  2. Reactive functions: Linking functions or methods to widgets using pn.bind or the equivalent pn.depends decorator, declaring that the function should be re-run when those widget values change
  3. Parameterized class: Declare parameters and their ranges in Parameterized classes, then get GUIs (and value checking!) for free
  4. Callbacks: Generate a UI by manually declaring callbacks that update panels or panes

First we need dataset autompg.

import hvplot.pandas
from bokeh.sampledata.autompg import autompg

def autompg_plot(x='mpg', y='hp', color='#058805'):
    return autompg.hvplot.scatter(x, y, c=color, padding=0.1)

columns = list(autompg.columns[:-2])
autompg_plot()

To control the color and widgets, we use panel components to manipulate.

Reactive Functions

Pros

  1. Very clear mapping from widgets to the arguments of the function.
  2. Like interact, doesn’t typically require modifying existing visualization code.

Cons

Typically requires a bit more code than interact.

pn.bind() helps bind specific arguments to a function.

def fn(a,b): return f'Arguments: {a,b}'
slider = pn.widgets.FloatSlider(value=0.5)

bound_fn = pn.bind(fn, a=slider, b=2)
bound_fn()
pn.Row(slider, bound_fn)

If you are writing code specifically for building an app, and do not wish to keep domain and GUI code separate, the functionality of pn.bind is also available as a decorator @pn.depends:

x = pn.widgets.Select(value='mpg', options=columns, name='x')
y = pn.widgets.Select(value='hp', options=columns, name='y')
color = pn.widgets.ColorPicker(name='Color', value='#AA0505')

@pn.depends(x, y, color)
def plot(xval, yval, colorval):
    return autompg.hvplot.scatter(xval, yval, c=colorval)

pn.Row(
    pn.Column('## MPG Explorer', x, y, color),
    plot
)

pn.bind() is preferred, because it it allows you to keep the Panel-specific code separate.

Interact Functions

Pros

Easy to use.

Parameterized Classes

Pros:

Declarative way of expressing parameters and dependencies between parameters and computation

The resulting code is not tied to any particular GUI framework and can be used in other contexts as well

Cons:

Requires writing classes

Less explicit about widgets to use for each parameter; can be harder to customize behavior than if widgets are instantiated explicitly

import param

class MPGExplorer(param.Parameterized):

    x = param.Selector(objects=columns)
    y = param.Selector(default='hp', objects=columns)
    color = param.Color(default='#0f0f0f')

    @param.depends('x', 'y', 'color') # optional in this case
    def plot(self):
        return autompg_plot(self.x, self.y, self.color)

explorer = MPGExplorer()

pn.Row(explorer.param, explorer.plot)

Callbacks

Pros:

Complete and modular control over specific events

Cons:

Complexity grows very quickly with the number of callbacks

Have to handle initializing the plots separately

color = pn.widgets.ColorPicker(name='Color', value='#880588')

layout = pn.Row(
    pn.Column('## MPG Explorer', x, y, color),
    autompg_plot(x.value, y.value, color.value))

def update(event):
    layout[1].object = autompg_plot(x.value, y.value, color.value)

x.param.watch(update, 'value')
y.param.watch(update, 'value')
color.param.watch(update, 'value')

layout