Skip to content

Commit

Permalink
Add links notebook (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
xavArtley authored and philippjfr committed Jan 22, 2019
1 parent cbd1491 commit d0a32d5
Showing 1 changed file with 310 additions and 0 deletions.
310 changes: 310 additions & 0 deletions examples/user_guide/Links.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Links parameters in panel"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the [param user guide](Param.ipynb), we have seen how parameterized classes are transformed to user interface at free cost. However in certain cases, we need more customisation over widgets automatically generated. Indeed widgets created with `widgets` modules exposed more attributes and allow more possibilities.\n",
"\n",
"In this notebook we will see how to links custom panels between them:\n",
"\n",
" - links between `Parameters` of `Parameterized` classes (most of panel inherit from `param.Parameterized`) with `link` method\n",
" - links between `Parameters` and custom functions with `watch` method"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import param\n",
"import panel as pn\n",
"pn.extension()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Links between `params` of `Parameterized` classes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this example we will link a markdown panel to a text input widget"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mkdown_pane = pn.pane.Markdown('Markdown display')\n",
"mkdown_pane"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widget_text = pn.widgets.TextInput(value=mkdown_pane.object)\n",
"widget_text"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We verify both objects we want to link are `param.Parameterized` objects"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(isinstance(mkdown_pane, param.Parameterized), isinstance(widget_text, param.Parameterized))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Link of widget `value` attribute to the `object` attribute of the panel"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widget_text.link(mkdown_pane, value = 'object')\n",
"widget_text.value = 'New text' #above displays should reflect change"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Accessing to available parameters using `params` method"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widget_text.params()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Link `params` with `watch` method "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Previously we have seen how to link one to one parameters between to Parameterized classes. However value between `parameters` must be the same. Sometimes parameters are linked but values differ. In this case we will add a `watcher`. A `watcher` is a function called when the attribute is changed."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's see how to link the disabled property of a `TextInput` widget to a `ToggleButton`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"widget text creation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widget_text = pn.widgets.TextInput(value='text', disabled=True)\n",
"widget_text"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"toggle button creation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widget_toggle = pn.widgets.Toggle(active=False, name='Click to enable text')\n",
"widget_toggle"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We could link toggle `active` parameter to the text widget `disabled` parameter with:\n",
"```python\n",
"widget_toggle.link(widget_text, active = 'disabled')\n",
"```\n",
"However we want the opposite behavior, when toggle is `active=True` text input is enabled (`disabled=False`)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To do it we use the `watch` method of the class `parameters` to connect the toggle button to the text input"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"watcher = widget_toggle.param.watch(lambda change: setattr(widget_text, 'disabled', not change.new), 'active' )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now cliking on the toggle button enable or disable the text input"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`param.watch` return a reference to the watcher which can be used to remove it."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widget_toggle.param.unwatch(watcher)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"the two widgets are not linked anymore"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## More advance usage"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the `Sine` example of the [param user guide](Param.ipynb), we will create sliders with a custom step value. Indeed the default step of sliders automatically generated is 0.1 and is not always adapted."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"class Sine(param.Parameterized):\n",
"\n",
" phase = param.Number(default=0, bounds=(0, np.pi))\n",
"\n",
" frequency = param.Number(default=1, bounds=(0.1, 2))\n",
" \n",
" \n",
" def widgets(self):\n",
" phase_params = self.params()['phase']\n",
" frequency_params = self.params()['frequency']\n",
" phase_slider = pn.widgets.FloatSlider(value=phase_params.default,\n",
" start=phase_params.bounds[0],\n",
" end=phase_params.bounds[1], step=1e-2)\n",
" frequency_slider = pn.widgets.FloatSlider(value=frequency_params.default,\n",
" start=frequency_params.bounds[0],\n",
" end=frequency_params.bounds[1], step=1e-2)\n",
" phase_slider.link(self, value='phase')\n",
" frequency_slider.link(self, value='frequency')\n",
" return pn.widgets.WidgetBox(frequency_slider, phase_slider)\n",
"\n",
" @param.depends('phase', 'frequency')\n",
" def view(self):\n",
" y = np.sin(np.linspace(0, np.pi*3, 40)*self.frequency+self.phase)\n",
" y = ((y-y.min())/y.ptp())*20\n",
" array = np.array([list((' '*(int(round(d))-1) + '*').ljust(20)) for d in y])\n",
" return pn.pane.Str('\\n'.join([''.join(r) for r in array.T]), height=325, width=500)\n",
"\n",
"sine = Sine(name='ASCII Sine Wave')\n",
"pn.panel(pn.Row(sine.widgets(), sine.view))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit d0a32d5

Please sign in to comment.