Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add throttled argument to pn.param widgets parameter #1800

Merged
merged 6 commits into from
Dec 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion examples/reference/panes/Param.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model building\n",
"Let's build a model of a cycling Athlete and her PowerCurve. \n",
"\n",
"The PowerCurve is a recording of her maximum power output in Watt per kg for fixed durations of time."
Expand Down Expand Up @@ -325,12 +326,54 @@
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Disabling continuous updates for slider widgets\n",
"When a function takes a long time to run and depends on a parameter, realtime feedback can be a burden instead of being helpful.\n",
"\n",
"Therefore if a slider widget is used for a parameter and you have a function which takes long time to calculate, you can set the `throttled` keyword in the `panel.param.widgets` to `True` for the given parameter. This will then first run the function after the release of the mouse button of the slider.\n",
"\n",
"An example can be seen below where two parameters is connected to two sliders, one with and one without `throttled` enabled."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
"source": [
"class A(param.Parameterized):\n",
" without_throttled_enabled = param.Range(\n",
" default=(100, 250),\n",
" bounds=(0, 250),\n",
" )\n",
"\n",
" with_throttled_enabled = param.Range(\n",
" default=(100, 250),\n",
" bounds=(0, 250),\n",
" )\n",
"\n",
" def __init__(self, **params):\n",
" super().__init__(**params)\n",
" widgets = {\n",
" \"without_throttled_enabled\": pn.widgets.IntRangeSlider,\n",
" \"with_throttled_enabled\": {\n",
" \"type\": pn.widgets.IntRangeSlider,\n",
" \"throttled\": True,\n",
" },\n",
" }\n",
" self.controls = pn.Param(self, widgets=widgets)\n",
"\n",
" @param.depends(\"controls\")\n",
" def calculation(self):\n",
" return self.without_throttled_enabled, self.with_throttled_enabled\n",
"\n",
"\n",
"a = A()\n",
"pn.Column(a.controls, a.calculation)"
]
}
],
"metadata": {
Expand Down
4 changes: 4 additions & 0 deletions panel/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ def event(change):
def action(change):
value(self.object)
watcher = widget.param.watch(action, 'clicks')
elif kw_widget.get('throttled', False) and hasattr(widget, 'value_throttled'):
watcher = widget.param.watch(link_widget, 'value_throttled')
else:
watcher = widget.param.watch(link_widget, 'value')
watchers.append(watcher)
Expand Down Expand Up @@ -462,6 +464,8 @@ def action(event):
idx = self._callbacks.index(prev_watcher)
self._callbacks[idx] = watchers[0]
return
elif kw_widget.get('throttled', False) and hasattr(widget, 'value_throttled'):
updates['value_throttled'] = change.new
else:
updates['value'] = change.new

Expand Down
41 changes: 41 additions & 0 deletions panel/tests/test_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,47 @@ class Test(param.Parameterized):
assert number.height == 100
assert isinstance(text, TextInput)


def test_set_widgets_throttled(document, comm):
class Test(param.Parameterized):
a = param.Number(default=0, bounds=(0, 10), precedence=1)

test = Test()
pane = Param(test)
model = pane.get_root(document, comm=comm)

pane.widgets = {"a": {"throttled": False}}
assert len(model.children) == 2
_, number = model.children

number.value = 1
assert number.value == 1
assert number.value_throttled != 1
assert test.a == 1

test.a = 2
assert number.value == 2
assert number.value_throttled != 2
assert test.a == 2

# By setting throttled to true,
# `test.a` is linked to `number.value_throttled`
# instead of `number.value`.
pane.widgets = {"a": {"throttled": True}}
assert len(model.children) == 2
_, number = model.children

number.value_throttled = 3
assert number.value != 3
assert number.value_throttled == 3
assert test.a == 3

test.a = 4
assert number.value != 4
assert number.value_throttled == 4
assert test.a == 4


def test_set_show_name(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10))
Expand Down