Skip to main content
Ctrl+K
Logo image

Site Navigation

  • Getting Started
  • How-to
  • Explanation
  • Component Gallery
  • App Gallery
  • API Reference
  • Upgrade Guide
  • FAQ
  • About
  • Developer Guide

Site Navigation

  • Getting Started
  • How-to
  • Explanation
  • Component Gallery
  • App Gallery
  • API Reference
  • Upgrade Guide
  • FAQ
  • About
  • Developer Guide

FOR USERS

  • Getting Started
    • Installation
    • Build an app
    • Core Concepts
  • How-to
    • Prepare to develop
      • Develop in a notebook
        • Display Output in Notebooks
        • Develop in other notebook environments
      • Develop in an editor
        • Develop Apps in an Editor
        • Write apps in Markdown
    • Build apps
      • Construct individual components
        • Construct Panes
        • Access Pane Type
        • Access and Set Widget Values
        • Add or Remove Components from Panels
      • Styling components
        • Apply a Design
        • Toggling themes
        • Apply CSS
        • Customize Loading Icon
        • Control Visibility
      • Interactivity
        • Add interactivity to a function
        • Add interactivity with generators
        • Add reactivity to components
        • Make interactive data workflows
      • Arranging components
        • Customize Spacing
        • Align Components
        • Control Size
    • Use specialized UIs and APIs
      • Build a sequential UI
        • Create a Pipeline
        • Customize Pipeline Layout
        • Control Pipeline Flow
      • Build custom components
        • Combine Existing Components
        • Build Components from Scratch
      • Explicitly link parameters (Callbacks API)
        • Create High-Level Python Links with .link
        • Create Low-Level Python Links Using .watch
        • Link Two Objects in Javascript
        • Link Plot Parameters in Javascript
        • Link Many Objects in Javascript
      • Generate UIs from declared parameters (Declarative API)
        • Generate Widgets from Parameters
        • Declare Custom Widgets
        • Declare parameter dependencies
        • Create nested UIs
    • Manage session tasks
      • Register Session Callbacks
        • Use Asynchronous Callbacks
        • Defer Long Running Tasks to Improve the User Experience
        • Run Tasks at Session Start or End
        • Periodically Run Callbacks
        • Schedule Global Tasks
        • Modify Bokeh Models
      • Access Session State
        • Access and Manipulate the URL
        • Access HTTP Request State
        • Access Busyness state
    • Test and debug
      • Enable profiling and debugging
        • Enable the admin panel
        • Profile your Application
        • View application logs
      • Set up testing for an application
        • Test functionality and performance
        • Test UI rendering
        • Test operating capacity
    • Prepare to share
      • Apply Templates
        • Set a Template
        • Arrange Components in a Template
        • Toggle Modal
        • Customize Template Theme
        • Build a Custom Template
      • Improve Performance
        • Reuse sessions
        • Enable Throttling
      • Cache Data
        • Manually Cache
        • Automatically Cache
      • Improve Scalability
        • Load balancing
        • Launch multiple processes
        • Enable Automatic Threading
        • Use Asynchronous Processing
      • Add Authentication
        • Configuring Basic Authentication
        • Configuring OAuth
        • OAuth Providers
        • Accessing User information
    • Share your work
      • Configure the server
        • Launching a server on the commandline
        • Launching a server dynamically
        • Serving multiple applications
        • Connect to a remote server via SSH
        • Configuring a reverse proxy
        • Serving static files
      • Integrate with other servers
        • Integrating Panel with Flask
        • Integrating Panel with FastAPI
        • Running Panel apps inside Django
      • Deploy applications
        • Microsoft Azure
        • MyBinder
        • Google Cloud Platform (GCP)
        • Heroku
        • Hugging Face
      • Export apps
        • Embedding state
        • Save App to File
        • Access the Bokeh Model
      • Run panel in WebAssembly
        • Converting Panel applications
        • Using Panel in Pyodide & PyScript
        • Embedding in Sphinx documentation
        • Setting up JupyterLite
    • Migrate to Panel
      • Migrate from Streamlit
        • Get Started migrating from Streamlit to Panel
        • Displaying Content with Panes
        • Organize Components with Layouts
        • Accepting User Inputs with Widgets
        • Organize and Style with Templates
        • Show Activity
        • Add Interactivity with pn.bind
        • Improve the performance with Caching
        • Session State
        • Multi Page Apps
  • Explanation
    • APIs
      • API context
        • Reactive API
        • Declarative API
        • Callbacks
    • Components
      • Components overview
      • Custom components
    • Linking
      • Panel and JS communications
    • Styling
      • Templates
    • Dependencies
      • Panel and Param
      • Panel and Bokeh
    • Technology comparisons
      • Panel vs Dash
      • Panel vs ipywidgets
      • Panel vs Voila
      • Panel vs Streamlit
      • Panel vs JavaScript
      • Panel vs Bokeh
  • Component Gallery
    • Panes
      • Alert
      • Audio
      • Bokeh
      • DataFrame
      • DeckGL
      • ECharts
      • Folium
      • GIF
      • HTML
      • HoloViews
      • IPyWidget
      • Image
      • JPG
      • JSON
      • LaTeX
      • Markdown
      • Matplotlib
      • PDF
      • PNG
      • Param
      • Perspective
      • Plotly
      • Reacton
      • SVG
      • Str
      • Streamz
      • VTK
      • VTKJS
      • VTKVolume
      • Vega
      • Video
      • Vizzu
    • Layouts
      • Accordion
      • Card
      • Column
      • Divider
      • FlexBox
      • FloatPanel
      • GridBox
      • GridSpec
      • GridStack
      • Row
      • Swipe
      • Tabs
      • WidgetBox
    • Templates
      • Bootstrap
      • FastGridTemplate
      • FastListTemplate
      • GoldenLayout
      • Material
      • React
      • Slides
      • Vanilla
    • Global
      • Notifications
    • Indicators
      • BooleanStatus
      • Dial
      • Gauge
      • LinearGauge
      • LoadingSpinner
      • Number
      • Progress
      • TooltipIcon
      • Tqdm
      • Trend
    • Widgets
      • ArrayInput
      • AutocompleteInput
      • Button
      • ChatBox
      • CheckBoxGroup
      • CheckButtonGroup
      • Checkbox
      • CodeEditor
      • ColorPicker
      • CrossSelector
      • DataFrame
      • DatePicker
      • DateRangeSlider
      • DateSlider
      • DatetimeInput
      • DatetimePicker
      • DatetimeRangeInput
      • DatetimeRangePicker
      • DatetimeRangeSlider
      • Debugger
      • DiscretePlayer
      • DiscreteSlider
      • EditableFloatSlider
      • EditableIntSlider
      • EditableRangeSlider
      • FileDownload
      • FileInput
      • FileSelector
      • FloatInput
      • FloatSlider
      • IntInput
      • IntRangeSlider
      • IntSlider
      • JSONEditor
      • LiteralInput
      • MenuButton
      • MultiChoice
      • MultiSelect
      • PasswordInput
      • Player
      • RadioBoxGroup
      • RadioButtonGroup
      • RangeSlider
      • Select
      • SpeechToText
      • StaticText
      • Switch
      • Tabulator
      • Terminal
      • TextAreaInput
      • TextEditor
      • TextInput
      • TextToSpeech
      • Toggle
      • ToggleGroup
      • VideoStream
  • App Gallery
    • Portfolio Optimizer
    • Streaming Videostream
    • Windturbines
    • Portfolio Analyzer
    • Glaciers
    • Vtk Slicer
    • Nyc Deckgl
    • Gapminders
    • Vtk Interactive
    • Penguin Crossfilter
    • Deckgl Game Of Life
    • Hvplot Explorer
    • Xgboost Classifier
    • Altair Brushing
    • Vtk Warp
    • Iris Kmeans
    • Penguin Kmeans
  • API Reference
    • Cheat Sheet
    • Config
    • State
    • panel.io Package
    • panel.layout Package
    • panel.pane Package
      • panel.vtk Package
    • param Module
    • pipeline Module
    • panel.template Package
      • panel.bootstrap Package
      • panel.fast Package
        • panel.grid Package
        • panel.list Package
      • panel.golden Package
      • panel.material Package
      • panel.react Package
      • panel.slides Package
      • panel.vanilla Package
    • panel.util Package
    • viewable Module
    • panel.widgets Package
  • Upgrade Guide
  • FAQ
  • About
    • Releases

FOR DEVELOPERS

  • Developer Guide
    • Testing
  • How-to
  • Link Parameters with Callbacks API
  • Create Low-Level Python Links Using .watch

Create Low-Level Python Links Using .watch#

This guide addresses how to use the low-level .watch API to trigger callbacks on parameters.

Prerequisites

  1. The How to > Create High-Level Python Links with ‘.link’ guide demonstrates a high-level API to link to parameters, which is adequate in most cases.


If we need more control than what .link provides, we can fall back to the underlying .watch method. The main differences are that .watch:

  1. does not assume you are linking two objects (providing more control over what you are watching)

  2. allows batched callbacks when multiple parameters change at once

  3. allows you to specify that an event should be triggered every time the parameter is set (instead of the default of only when the parameter value actually changes)

To demonstrate .watch, let us set up three different models:

  1. Markdown pane to display the possible options

  2. Markdown pane to display the selected options

  3. ToggleGroup widget that allows us to toggle between a number of options

import panel as pn

pn.extension()

selections = pn.pane.Markdown(object='')
selected = pn.pane.Markdown(object='')
toggle = pn.widgets.ToggleGroup(options=['A', 'B'])

Defining a callback#

Next we define a callback that can handle multiple parameter changes at once and uses the Event’s name to figure out how to process the event. In this case it updates either the selections or the selected pane depending on whether ToggleGroup options or value changed:

def callback(*events):
    print(events)
    for event in events:
        if event.name == 'options':
            selections.object = 'Possible options: %s' % ', '.join(event.new)
        elif event.name == 'value':
            selected.object = 'Selected: %s' % ','.join(event.new)

Event objects#

Before going any further let us discover what these Event objects are. An Event is used to signal the change in a parameter value. Event objects provide a number of useful attributes that provides additional information about the event:

  • name: The name of the parameter that has changed

  • new: The new value of the parameter

  • old: The old value of the parameter before the event was triggered

  • type: The type of event (‘triggered’, ‘changed’, or ‘set’)

  • what: Describes what about the parameter changed (usually the value but other parameter attributes can also change)

  • obj: The Parameterized instance that holds the parameter

  • cls: The Parameterized class that holds the parameter

Registering a watcher#

Now that we know how to define a callback and make use of Event attributes, it is time to register the callback. The obj.param.watch method lets us supply the callback along with the parameters we want to watch. Additionally we can declare whether the events should only be triggered when the parameter value changes, or every time the parameter is set:

watcher = toggle.param.watch(callback, ['options', 'value'], onlychanged=False)

Now let us display the widget alongside the Markdown panes that reflect the current state of the widget:

pn.Row(pn.Column(toggle, width=200, height=50), selections, pn.Spacer(width=50, height=50), selected)

To initialize the selections and selected we can explicitly trigger options and value events:

toggle.param.trigger('options', 'value')
(Event(what='value', name='options', obj=CheckButtonGroup(options=['A', 'B']), cls=CheckButtonGroup(options=['A', 'B']), old=['A', 'B'], new=['A', 'B'], type='triggered'), Event(what='value', name='value', obj=CheckButtonGroup(options=['A', 'B']), cls=CheckButtonGroup(options=['A', 'B']), old=[], new=[], type='triggered'))

We can also override the initial parameters using the update method:

options = ['A','B','C','D']
toggle.param.update(options=dict(zip(options,options)), value=['D'])
(Event(what='value', name='options', obj=CheckButtonGroup(options={'A': 'A', 'B': 'B', ...}, value=['D']), cls=CheckButtonGroup(options={'A': 'A', 'B': 'B', ...}, value=['D']), old=['A', 'B'], new={'A': 'A', 'B': 'B', 'C': 'C', 'D': 'D'}, type='set'), Event(what='value', name='value', obj=CheckButtonGroup(options={'A': 'A', 'B': 'B', ...}, value=['D']), cls=CheckButtonGroup(options={'A': 'A', 'B': 'B', ...}, value=['D']), old=[], new=['D'], type='set'))
<param.parameterized._ParametersRestorer object at 0x11166dc10>

Using update allows us to batch two separate changes (the options and the value) together, which you can see from the print output resulted into a single invocation of the callback. You could instead have set them separately using the usual parameter-setting syntax toggle.value=['D']; toggle.options=dict(zip(options,options)), but batching them can be much more efficient for a non-trivial callback like a database query or a complex plot that needs updating.

Now that the widgets are visible, you can toggle the option values and see the selected pane update in response via the callback (if Python is running).

Unlinking#

If for whatever reason we want to stop watching parameter changes we can unsubscribe by passing our watcher (returned in the watch call above) to the unwatch method:

toggle.param.unwatch(watcher)

Related Resources#

  • See the Explanation > APIs for context on this and other Panel APIs

previous

Create High-Level Python Links with .link

next

Link Two Objects in Javascript

Support us with a star on GitHub
On this page
  • Defining a callback
  • Event objects
  • Registering a watcher
  • Unlinking
  • Related Resources

© Copyright 2019-2023 Holoviz contributors.

Created using Sphinx 5.3.0.

Built with the PyData Sphinx Theme 0.13.3.