This notebook is meant to show you some very recent developments in the iPython ecosystem that will likely revolutionize the way we work with data, interact with and evaluate mathematical functions and think about physics.

Created from the widget documentation pages.

```
In [ ]:
```%pylab inline
import matplotlib.pyplot as plt
import numpy as np

```
In [ ]:
```#import widgets
from ipywidgets import widgets

```
In [ ]:
```mywidget = widgets.FloatSlider()
display(mywidget)

`widget`

object with:

```
In [ ]:
```print mywidget.value

```
In [ ]:
```def on_value_change(name, value):
print(value)
int_range = widgets.IntSlider(min=0, max=10, step=2)
int_range.observe(on_value_change, 'value')
display(int_range)

```
In [ ]:
```def click_handler(widget):
print "clicked"
b = widgets.Button(description='Click Me!')
b.on_click(click_handler)
display(b)

`Interact`

and `Interactive`

are two other new tools that build on the widgets library to allow you to use Matplotlib to explore and visualize functions or data with varying parameters.

```
In [ ]:
```from ipywidgets import interact, interactive # Widget definitions

`interact`

object with the function and specified ranges for those parameters. The `interact`

object displayed will give you sliders (`widget`

s) that let you vary the input parameters and interactively see how they change the plot!

`interact`

object:

```
In [ ]:
```def linear_plot(m=0.5, b=27.0):
'''
Create a plot of some data that should
vary linearly along with a straight line
function with the given slope and intercept.
'''
#data to optimize
datax = np.array([1.0,2.0,3.0,5.0,7.0,9.0])
datay = np.array([10.2, 20.5, 24.8, 30.7, 33.6, 37.3])
erry = np.array([1.0,0.5,2.6,1.0,5.6,6.0])
#plot the data
plt.errorbar(datax,datay,xerr=0.0,yerr=erry,fmt='o')
#create a function to approximate the data using the slope
#and intercept parameters passed to the function
steps = 100
x = np.linspace(0,10.,steps)
y = m*x+b
#plot and show the result
plt.plot(x,y)
plt.xlim(0.,10.)
plt.ylim(0.,50.)
plt.show()
#Create an interactive plot with sliders for varying the slope and intercept
v = interact(linear_plot,m=(0.0,5.0), b=(0.0,50.0))

```
In [ ]:
```#Human optimizer results
#Best slope (m):
#Best y-intercept (b):

```
In [ ]:
```def scatter_plot(r=0.5, n=27):
t = np.random.uniform(0.0,2.0*np.pi,n)
rad = r*np.sqrt(np.random.uniform(0.0,1.0,n))
x = np.empty(n)
y = np.empty(n)
x = rad*np.cos(t)
y = rad*np.sin(t)
fig = plt.figure(figsize=(4,4),dpi=80)
plt.scatter(x,y)
plt.xlim(-1.,1.)
plt.ylim(-1.,1.)
plt.show()
v2 = interact(scatter_plot,r=(0.0,1.0), n=(1,1000))

```
In [ ]:
```def sin_plot(A=5.0,f1=5.0,f2=10.):
x = np.linspace(0,2*np.pi,1000)
#pure sine curve
y = A*np.sin(f1*x)
#superposition of sine curves with different frequency
#but same amplitude
y2 = A*(np.sin(f1*x)+np.sin(f2*x))
plt.plot(x,y,x,y2)
plt.xlim(0.,2.*np.pi)
plt.ylim(-10.,10.)
plt.grid()
plt.show()
v3 = interact(sin_plot,A=(0.,10.), f1=(1.0,10.0), f2=(1.0,10.0))

```
In [ ]:
``````
#Your code here
```

```
In [ ]:
```def lissajous_plot(a1=0.5,f1=1.,p1=0.,a2=0.5,f2=1.,p2=0.):
t = np.linspace(0, 20*np.pi, 5000)
x = a1*np.sin(f1*(t+p1))
y = a2*np.cos(f2*(t+p2))
plt.plot(x,y)
plt.xlim(-1.,1.)
plt.ylim(-1.,1.)
plt.show()
v4 = interact(lissajous_plot,a1=(0.,1.), f1=(1.0,4.0), p1=(0.,2*np.pi),
a2=(0.,1.),f2=(1.0,4.0),p2=(0.,2*np.pi))

Try playing with the curves by adjusting the sliders to make interesting patterns.

**Record three parameter combinations that lead to interesting shapes, then create new static plots in other cells to show what they look like.**