Skip to content

Commit 0598e0e

Browse files
authored
Merge pull request #8 from mwcraig/update-intro
Add revised introduction notebook
2 parents b405f55 + 9990509 commit 0598e0e

File tree

7 files changed

+4866
-0
lines changed

7 files changed

+4866
-0
lines changed
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"from ipywidgets import interact, interactive, fixed, interact_manual\n",
10+
"import ipywidgets as widgets"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"<!--NAVIGATION-->\n",
18+
"< [Widgets without writing widgets: interact](02.00-Using-Interact.ipynb) | [Contents](00.00-index.ipynb) | [Simple Widget Introduction](03.00-Widget_Basics.ipynb) >"
19+
]
20+
},
21+
{
22+
"cell_type": "markdown",
23+
"metadata": {},
24+
"source": [
25+
"# OPTIONAL - More about interact\n",
26+
"\n",
27+
"This notebook describes more ways to autogenerate widgets."
28+
]
29+
},
30+
{
31+
"cell_type": "markdown",
32+
"metadata": {},
33+
"source": [
34+
"## `interactive`\n",
35+
"\n",
36+
"In addition to `interact`, IPython provides another function, `interactive`, that is useful when you want to reuse the widgets that are produced or access the data that is bound to the UI controls.\n",
37+
"\n",
38+
"Note that unlike `interact`, the return value of the function will not be displayed automatically, but you can display a value inside the function with `IPython.display.display`."
39+
]
40+
},
41+
{
42+
"cell_type": "markdown",
43+
"metadata": {},
44+
"source": [
45+
"Here is a function that displays the sum of its two arguments and returns the sum. The `display` line may be omitted if you don't want to show the result of the function."
46+
]
47+
},
48+
{
49+
"cell_type": "code",
50+
"execution_count": null,
51+
"metadata": {},
52+
"outputs": [],
53+
"source": [
54+
"from IPython.display import display\n",
55+
"\n",
56+
"def f(a, b):\n",
57+
" display(a + b)\n",
58+
" return a+b"
59+
]
60+
},
61+
{
62+
"cell_type": "markdown",
63+
"metadata": {},
64+
"source": [
65+
"Unlike `interact`, `interactive` returns a `Widget` instance rather than immediately displaying the widget."
66+
]
67+
},
68+
{
69+
"cell_type": "code",
70+
"execution_count": null,
71+
"metadata": {},
72+
"outputs": [],
73+
"source": [
74+
"w = interactive(f, a=10, b=20)"
75+
]
76+
},
77+
{
78+
"cell_type": "markdown",
79+
"metadata": {},
80+
"source": [
81+
"The widget is an `interactive`, a subclass of `VBox`, which is a container for other widgets."
82+
]
83+
},
84+
{
85+
"cell_type": "code",
86+
"execution_count": null,
87+
"metadata": {},
88+
"outputs": [],
89+
"source": [
90+
"type(w)"
91+
]
92+
},
93+
{
94+
"cell_type": "markdown",
95+
"metadata": {},
96+
"source": [
97+
"The children of the `interactive` are two integer-valued sliders and an output widget, produced by the widget abbreviations above."
98+
]
99+
},
100+
{
101+
"cell_type": "code",
102+
"execution_count": null,
103+
"metadata": {},
104+
"outputs": [],
105+
"source": [
106+
"w.children"
107+
]
108+
},
109+
{
110+
"cell_type": "markdown",
111+
"metadata": {},
112+
"source": [
113+
"To actually display the widgets, you can use IPython's `display` function."
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"execution_count": null,
119+
"metadata": {},
120+
"outputs": [],
121+
"source": [
122+
"display(w)"
123+
]
124+
},
125+
{
126+
"cell_type": "markdown",
127+
"metadata": {},
128+
"source": [
129+
"At this point, the UI controls work just like they would if `interact` had been used. You can manipulate them interactively and the function will be called. However, the widget instance returned by `interactive` also gives you access to the current keyword arguments and return value of the underlying Python function. \n",
130+
"\n",
131+
"Here are the current keyword arguments. If you rerun this cell after manipulating the sliders, the values will have changed."
132+
]
133+
},
134+
{
135+
"cell_type": "code",
136+
"execution_count": null,
137+
"metadata": {},
138+
"outputs": [],
139+
"source": [
140+
"w.kwargs"
141+
]
142+
},
143+
{
144+
"cell_type": "markdown",
145+
"metadata": {},
146+
"source": [
147+
"Here is the current return value of the function."
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": null,
153+
"metadata": {},
154+
"outputs": [],
155+
"source": [
156+
"w.result"
157+
]
158+
},
159+
{
160+
"cell_type": "markdown",
161+
"metadata": {},
162+
"source": [
163+
"## Disabling continuous updates"
164+
]
165+
},
166+
{
167+
"cell_type": "markdown",
168+
"metadata": {},
169+
"source": [
170+
"When interacting with long running functions, or even with short functions whose results take some to display, realtime feedback is a burden instead of being helpful. You might have noticed the output of some of the widgets above \"flickering\" as you adjusted the controls. By default, `interact` and `interactive` call the function for every update of the widgets value. "
171+
]
172+
},
173+
{
174+
"cell_type": "markdown",
175+
"metadata": {},
176+
"source": [
177+
"There are two ways to mitigate this. You can either only execute on demand, or restrict execution to mouse release events."
178+
]
179+
},
180+
{
181+
"cell_type": "markdown",
182+
"metadata": {},
183+
"source": [
184+
"### `interact_manual`"
185+
]
186+
},
187+
{
188+
"cell_type": "markdown",
189+
"metadata": {},
190+
"source": [
191+
"The `interact_manual` function provides a variant of interaction that allows you to restrict execution so it is only done on demand. A button is added to the interact controls that allows you to trigger an execute event."
192+
]
193+
},
194+
{
195+
"cell_type": "code",
196+
"execution_count": null,
197+
"metadata": {},
198+
"outputs": [],
199+
"source": [
200+
"def slow_function(i):\n",
201+
" \"\"\"\n",
202+
" Sleep for 1 second then print the argument\n",
203+
" \"\"\"\n",
204+
" from time import sleep\n",
205+
" print('Sleeping...')\n",
206+
" sleep(1)\n",
207+
" print(i)\n",
208+
"\n",
209+
"interact_manual(slow_function,i=widgets.FloatSlider(min=1e4, max=1e6, step=1e4));"
210+
]
211+
},
212+
{
213+
"cell_type": "markdown",
214+
"metadata": {},
215+
"source": [
216+
"You can do the same thing with `interactive` by using a `dict` as the second argument, as shown below."
217+
]
218+
},
219+
{
220+
"cell_type": "code",
221+
"execution_count": null,
222+
"metadata": {},
223+
"outputs": [],
224+
"source": [
225+
"foo = interactive(slow_function, {'manual': True}, i=widgets.FloatSlider(min=1e4, max=1e6, step=1e4))\n",
226+
"foo"
227+
]
228+
},
229+
{
230+
"cell_type": "markdown",
231+
"metadata": {},
232+
"source": [
233+
"### `continuous_update`"
234+
]
235+
},
236+
{
237+
"cell_type": "markdown",
238+
"metadata": {},
239+
"source": [
240+
"If you are using slider widgets, you can set the `continuous_update` kwarg to `False`. `continuous_update` is a keyword argument of slider widgets that restricts executions to mouse release events.\n",
241+
"\n",
242+
"In ipywidgets 7, the `Text` and `Textarea` controls also have a `continuous_update` argument.\n",
243+
"\n",
244+
"The first example below provides the `continuous_update` argument when the widget is created."
245+
]
246+
},
247+
{
248+
"cell_type": "code",
249+
"execution_count": null,
250+
"metadata": {},
251+
"outputs": [],
252+
"source": [
253+
"interact(slow_function,i=widgets.FloatSlider(min=1e4, max=1e6, step=5e4, continuous_update=False));"
254+
]
255+
},
256+
{
257+
"cell_type": "markdown",
258+
"metadata": {},
259+
"source": [
260+
"## More control over the user interface: `interactive_output`\n",
261+
"\n",
262+
"`interactive_output` provides additional flexibility: you can control how the UI elements are laid out.\n",
263+
"\n",
264+
"Unlike `interact`, `interactive`, and `interact_manual`, `interactive_output` does not generate a user interface for the widgets. This is powerful, because it means you can create a widget, put it in a box, and then pass the widget to `interactive_output`, and have control over the widget and its layout."
265+
]
266+
},
267+
{
268+
"cell_type": "code",
269+
"execution_count": null,
270+
"metadata": {},
271+
"outputs": [],
272+
"source": [
273+
"a = widgets.IntSlider()\n",
274+
"b = widgets.IntSlider()\n",
275+
"c = widgets.IntSlider()\n",
276+
"\n",
277+
"# An HBox lays out its children horizontally\n",
278+
"ui = widgets.HBox([a, b, c])\n",
279+
"\n",
280+
"def f(a, b, c):\n",
281+
" # You can use print here instead of display because interactive_output generates a normal notebook \n",
282+
" # output area.\n",
283+
" print((a, b, c))\n",
284+
"\n",
285+
"out = widgets.interactive_output(f, {'a': a, 'b': b, 'c': c})\n",
286+
"\n",
287+
"display(ui, out)"
288+
]
289+
},
290+
{
291+
"cell_type": "markdown",
292+
"metadata": {},
293+
"source": [
294+
"# For more information \n",
295+
"\n",
296+
"For more extended examples of `interact` and `interactive`, see [the example in the ipywidgets source repository](https://github.com/jupyter-widgets/ipywidgets/blob/master/docs/source/examples/Index.ipynb)."
297+
]
298+
},
299+
{
300+
"cell_type": "markdown",
301+
"metadata": {},
302+
"source": [
303+
"<!--NAVIGATION-->\n",
304+
"< [Widgets without writing widgets: interact](02.00-Using-Interact.ipynb) | [Contents](00.00-index.ipynb) | [Simple Widget Introduction](03.00-Widget_Basics.ipynb) >"
305+
]
306+
}
307+
],
308+
"metadata": {
309+
"kernelspec": {
310+
"display_name": "widgets-tutorial",
311+
"language": "python",
312+
"name": "widgets-tutorial"
313+
},
314+
"language_info": {
315+
"codemirror_mode": {
316+
"name": "ipython",
317+
"version": 3
318+
},
319+
"file_extension": ".py",
320+
"mimetype": "text/x-python",
321+
"name": "python",
322+
"nbconvert_exporter": "python",
323+
"pygments_lexer": "ipython3",
324+
"version": "3.8.3"
325+
}
326+
},
327+
"nbformat": 4,
328+
"nbformat_minor": 4
329+
}

0 commit comments

Comments
 (0)