#!/usr/bin/env python # coding: utf-8 # # Using Interact # The `interact` function (`IPython.html.widgets.interact`) automatically creates user interface (UI) controls for exploring code and data interactively. It is the easiest way to get started using IPython's widgets. # In[ ]: from __future__ import print_function from IPython.html.widgets import interact, interactive, fixed from IPython.html import widgets #
# As of IPython 3.0, the widgets in this notebook won't show up on http://nbviewer.ipython.org. To view the widgets and interact with them, you will need to download this notebook and run it with an IPython Notebook server. # #
# ## Basic `interact` # At the most basic level, `interact` autogenerates UI controls for function arguments, and then calls the function with those arguments when you manipulate the controls interactively. To use `interact`, you need to define a function that you want to explore. Here is a function that prints its only argument `x`. # In[ ]: def f(x): print(x) # When you pass this function as the first argument to `interact` along with an integer keyword argument (`x=10`), a slider is generated and bound to the function. # In[ ]: interact(f, x=10); # When you move the slider, the function is called and the current value of `x` is printed. # # If you pass `True` or `False`, `interact` will generate a checkbox: # In[ ]: interact(f, x=True); # If you pass a string, `interact` will generate a text area. # In[ ]: interact(f, x='Hi there!'); # `interact` can also be used as a decorator. This allows you to define a function and interact with it in a single shot. As this example shows, `interact` also works with functions that have multiple arguments. # In[ ]: @interact(x=True, y=1.0) def g(x, y): print(x, y) # ## Fixing arguments using `fixed` # There are times when you may want to explore a function using `interact`, but fix one or more of its arguments to specific values. This can be accomplished by wrapping values with the `fixed` function. # In[ ]: def h(p, q): print(p, q) # When we call `interact`, we pass `fixed(20)` for q to hold it fixed at a value of `20`. # In[ ]: interact(h, p=5, q=fixed(20)); # Notice that a slider is only produced for `p` as the value of `q` is fixed. # ## Widget abbreviations # When you pass an integer valued keyword argument (`x=10`) to `interact`, it generates an integer valued slider control with a range of $[-10,+3\times10]$. In this case `10` is an *abbreviation* for an actual slider widget: # # ```python # IntSlider(min=-10,max=30,step=1,value=10) # ``` # # In fact, we can get the same result if we pass this `IntSlider` as the keyword argument for `x`: # In[ ]: interact(f, x=widgets.IntSlider(min=-10,max=30,step=1,value=10)); # This examples clarifies how `interact` proceses its keyword arguments: # # 1. If the keyword argument is `Widget` instance with a `value` attribute, that widget is used. Any widget with a `value` attribute can be used, even custom ones. # 2. Otherwise, the value is treated as a *widget abbreviation* that is converted to a widget before it is used. # # The following table gives an overview of different widget abbreviations: # # # # # # # # #
Keyword argumentWidget
`True` or `False`Checkbox
`'Hi there'`Text
`value` or `(min,max)` or `(min,max,step)` if integers are passedIntSlider
`value` or `(min,max)` or `(min,max,step)` if floats are passedFloatSlider
`('orange','apple')` or `{'one':1,'two':2}`Dropdown
# You have seen how the checkbox and textarea widgets work above. Here, more details about the different abbreviations for sliders and dropdowns are given. # # If a 2-tuple of integers is passed `(min,max)` a integer valued slider is produced with those minimum and maximum (inclusive) values. In this case, the default step size of `1` is used. # In[ ]: interact(f, x=(0,4)); # If a 3-tuple of integers is passed `(min,max,step)` the step size can also be set. # In[ ]: interact(f, x=(0,8,2)); # A float valued slider is produced if the elements of the tuples are floats. Here the minimum is `0.0`, the maximum is `10.0` and step size is `0.1` (the default). # In[ ]: interact(f, x=(0.0,10.0)); # The step size can be changed by passing a 3rd element in the tuple. # In[ ]: interact(f, x=(0.0,10.0,0.01)); # For both integer and float valued sliders, you can pick the initial value of the widget by passing a default keyword argument to the underlying Python function. Here we set the initial value of a float slider to `5.5`. # In[ ]: @interact(x=(0.0,20.0,0.5)) def h(x=5.5): print(x) # Dropdown menus can be produced by passing a tuple of strings. In this case, the strings are both used as the names in the dropdown menu UI and passed to the underlying Python function. # In[ ]: interact(f, x=('apples','oranges')); # If you want a dropdown menu that passes non-string values to the Python function, you can pass a dictionary. The keys in the dictionary are used for the names in the dropdown menu UI and the values are the arguments that are passed to the underlying Python function. # In[ ]: interact(f, x={'one': 10, 'two': 20}); # ## Using function annotations with `interact` # If you are using Python 3, you can also specify widget abbreviations using [function annotations](https://docs.python.org/3/tutorial/controlflow.html#function-annotations). This is a convenient approach allows the widget abbreviations to be defined with a function. # # Define a function with an checkbox widget abbreviation for the argument `x`. # In[ ]: def f(x:True): print(x) # Then, because the widget abbreviation has already been defined, you can call `interact` with a single argument. # In[ ]: interact(f); # If you are running Python 2, function annotations can be defined using the `@annotate` function. # In[ ]: from IPython.utils.py3compat import annotate # In[ ]: @annotate(x=True) def f(x): print(x) # In[ ]: interact(f); # ## `interactive` # In addition to `interact` IPython provides another function, `interactive`, that is useful when you want to reuse the widget that are produced or access the data that is bound to the UI controls. # Here is a function that returns the sum of its two arguments. # In[ ]: def f(a, b): return a+b # Unlike `interact`, `interactive` returns a `Widget` instance rather than immediately displaying the widget. # In[ ]: w = interactive(f, a=10, b=20) # The widget is a `Box`, which is a container for other widgets. # In[ ]: type(w) # The children of the `Box` are two integer valued sliders produced by the widget abbreviations above. # In[ ]: w.children # To actually display the widgets, you can use IPython's `display` function. # In[ ]: from IPython.display import display display(w) # 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 give you access to the current keyword arguments and return value of the underlying Python function. # # Here are the current keyword arguments. If you rerun this cell after manipulating the sliders, the values will have changed. # In[ ]: w.kwargs # Here is the current return value of the function. # In[ ]: w.result