The interact
function ipywidgets.interact
is the quickest way to create user interface controls in code. It is the easiest way to get up and running!
import ipywidgets as widgets
interact
¶At the most basic level, interact
autogenerates 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.
def f(x):
return 3*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 parameter.
widgets.interact(f, x=10);
If you pass True
or False
, interact
will generate a checkbox:
widgets.interact(f, x=True);
If you pass a string, interact
will generate a Text
field.
widgets.interact(f, x='Hello!');
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.
@widgets.interact(x=True, y=1.0)
def g(x, y):
return (x, y)
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.
def h(p, q):
return (p, q)
widgets.interact(h, p=5, q=widgets.fixed(20));
When you pass an integer-valued keyword argument of 10
(x=10
) to interact
, it generates an integer-valued slider control with a range of [-10,+3*10]
. In this case, 10
is an abbreviation for an actual slider widget:
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
:
widgets.interact(
f, x=widgets.IntSlider(min=-10, max=30, step=1, value=10)
);
This examples clarifies how interact
proceses its keyword arguments:
Widget
instance with a value
attribute, that widget is used. Any widget with a value
attribute can be used, even custom ones.The following table gives an overview of different widget abbreviations:
Keyword argument | Widget |
`True` or `False` | Checkbox |
`'Hi there'` | Text |
`value` or `(min,max)` or `(min,max,step)` if integers are passed | IntSlider |
`value` or `(min,max)` or `(min,max,step)` if floats are passed | FloatSlider |
`['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)
, an integer-valued slider is produced with those minimum and maximum values (inclusively). In this case, the default step size of 1
is used.
widgets.interact(f, x=(0, 4));
A FloatSlider
is generated if any of the values are floating point. The step size can be changed by passing a third element in the tuple.
widgets.interact(f, x=(0., 10, 1));
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
.
@widgets.interact(x=(0.0, 20.0, 0.5))
def h(x=5.5):
return x
Dropdown menus are constructed by passing a list 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.
widgets.interact(f, x=['apples','oranges']);
If you want a dropdown menu that passes non-string values to the Python function, you can pass a list of tuples of the form ('label', value)
. The first items are the names in the dropdown menu UI and the second items are values that are the arguments passed to the underlying Python function.
widgets.interact(f, x=[('one', 10), ('two', 20)]);
interactive
¶interactive
is useful when you want to reuse the widgets that are produced or access the data that is bound to the UI controls.
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
.
from IPython.display import display
def f(a, b):
display(a + b)
return a+b
Unlike interact
, interactive
returns a Widget
instance rather than immediately displaying the widget.
w = widgets.interactive(f, a=10, b=20)
w
The widget is an interactive
, a subclass of VBox
, which is a container for other widgets.
type(w)
The children of the interactive
are two integer-valued sliders and an output widget, produced by the widget abbreviations above.
w.children
To actually display the widgets, you can use IPython's display
function.
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 gives 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.
w.kwargs
Here is the current return value of the function.
w.result
Though the examples so far in this notebook had very basic output, more interesting possibilities are straightforward.
The function below plots a straight line whose slope and intercept are given by its arguments.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
def f(m, b):
plt.figure(2)
x = np.linspace(-10, 10, num=1000)
plt.plot(x, m * x + b)
plt.ylim(-5, 5)
plt.show()
The interactive below displays a line whose slope and intercept is set by the sliders. Note that if the variable containing the widget, interactive_plot
, is the last thing in the cell it is displayed.
interactive_plot = widgets.interactive(f, m=(-2.0, 2.0), b=(-3, 3, 0.5))
interactive_plot
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.
There are two ways to mitigate this. You can either only execute on demand, or restrict execution to mouse release events.
interact_manual
¶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.
def slow_function(i):
"""
Sleep for 1 second then print the argument
"""
from time import sleep
print('Sleeping...')
sleep(1)
print(i)
widgets.interact_manual(slow_function,i=widgets.FloatSlider(min=1e4, max=1e6, step=1e4));
You can do the same thing with interactive
by using the a dict
as the second argument, as shown below.
foo = widgets.interactive(
slow_function, {'manual': True},
i=widgets.FloatSlider(min=1e4, max=1e6, step=1e4)
)
foo
continuous_update
¶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.
In ipywidgets 7, the Text
and Textarea
controls also have a continuous_update
argument.
The first example below provides the continuous_update
argument when the widget is created.
widgets.interact(
slow_function,
i=widgets.FloatSlider(min=1e4, max=1e6, step=5e4, continuous_update=False)
);
A Python widget is an object that represents a control on the front end, like a slider. A single control can be displayed multiple times - they all represent the same python object.
slider = widgets.FloatSlider(
value=7.5,
min=5.0,
max=10.0,
step=0.1,
description='$\phi$',
)
slider
slider
The control attributes, like its value, are automatically synced between the frontend and the kernel.
slider.value
slider.value = 8
You can trigger actions in the kernel when a control value changes by "observing" the value. Here we set a global variable when the slider value changes.
square = slider.value * slider.value
def handle_change(change):
global square
square = change.new * change.new
slider.observe(handle_change, 'value')
square
You can link control attributes and lay them out together.
text = widgets.FloatText(description='Value')
widgets.link((slider, 'value'), (text, 'value'))
widgets.VBox([slider, text])
For more extended examples of interact
and interactive
, see the example in the ipywidgets source repository.