# Import modules
import ipywidgets as widgets
31 Widgets
Adding interactivity to Jupyter notebooks can be a great way of improving exploratory data analysis and real-time interactive data visualization. The ipywidgets library provides a powerful toolset for creating interactive widget elements like sliders, dropdowns, and buttons in Jupyter notebooks.
The following examples will demonstrate:
- the basic syntax to create widgets and set custom parameters
- how to define a function that ingests widget values
- how to connect the widget and the function
The widgets may not appear in the online version of the tutorial. Either copy the code and run it in your local Jupyter notebook or download the notebook from the Github repository.
Example 1: Convert bushels to metric tons
A common task in agronomy is to convert grain yields from bushels to metric tons. We will use ipywidgets
to create interactive dropdowns and slider widgets to facilitate the convertion between these two units for common crops.
# Define widget
= widgets.Dropdown(options=['Barley','Corn','Sorghum','Soybeans','Wheat'],
crop_dropdown ='Wheat', description='Crop')
value= widgets.FloatSlider(value=40, min=0, max=200, step=1,
bushels_slider ='Bushels/acre')
description
# Define function
def bushels_to_tons(crop, bu):
"""Function that converts bushels to metric tons for common crops.
Source: https://grains.org/
"""
# Define constants
= 0.453592/1000
lbs_per_ton = 2.47105
acres_per_ha
# Convert bu -> lbs -> tons
if crop == 'Barley':
= bu * 48 * lbs_per_ton
tons
elif crop == 'Corn' or crop == 'Sorghum':
= bu * 56 * lbs_per_ton
tons
elif crop == 'Wheat' or crop == 'Soybeans':
= bu * 60 * lbs_per_ton
tons
# Convert acre -> hectares
= round(tons * acres_per_ha, 2)
tons return widgets.FloatText(value=tons, description='Tons/ha', disabled=True)
# Define interactivity
=crop_dropdown, bu=bushels_slider); widgets.interact(bushels_to_tons, crop
Example 2: Runoff-Precipitation
Widgets are also a great tool to explore and learn how models representing real-world processes respond to input changes. In this example we will explore how the curve number of a soil is related to the amount of runoff for a range of precipitation amounts.
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
'ggplot') plt.style.use(
# Create widget
= widgets.IntSlider(50, min=1, max=100, description='Curve number')
cn_slider
# Create function
def estimate_runoff(cn):
"""Function that computes runoff based on the
curve number method proposed by the Soil Conservation Service
Source: https://www.wikiwand.com/en/Runoff_curve_number
Inputs
cn : Curve number. 0 means fully permeable and 100 means fully impervious.
Returns
Figure of runoff as a function of precipitation
"""
= np.arange(0, 12, step=0.01) # Precipitation in inches
P = np.zeros_like(P)
RO = 1000/cn - 10
S = S * 0.05 # Initial abstraction (inches)
Ia = P > Ia
idx = (P[idx] - Ia)**2 / (P[idx] - Ia + S)
RO[idx]
# Create figure
=(6,4))
plt.figure(figsize'--k')
plt.plot(P,RO,'Curve Number Method')
plt.title('Precipitation (inches)')
plt.xlabel('Runoff (inches)')
plt.ylabel(0,12])
plt.xlim([0,12])
plt.ylim([return plt.show()
# Define interactivity
=cn_slider); widgets.interact(estimate_runoff, cn