{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Creating Sliders in Jupyter Notebooks\n", "\n", "This notebook illustrates how to create sliders using `ipywidgets` for interactive plots.\n", "\n", "### Credits:\n", "Some materials developed in this notebook were inspired by https://github.com/jckantor/CBE30338" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Simple Slider" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll start by creating a plot to visualize the step response of a transfer function. We'll use an ipywidgets slider to manipulate process parameters and see how the response changes with $K_p$ and $\\tau_I$." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Import the libraries we'll need\n", "%matplotlib inline\n", "%config InlineBackend.figure_formats = {'svg',} # svg makes the figures look nicer\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import control\n", "import warnings\n", "warnings.filterwarnings('ignore') #suppress all warnings" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Define the transfer function\n", "def tf(K_p, tau_I, print_variables=False):\n", " G = control.tf([1],[1,0]) # Transfer function for the process\n", " G_c = K_p*control.tf([tau_I,1],[tau_I*1,0]) # Transfer function for the controller\n", " sys = G_c*G/(1+G_c*G) # The closed loop transfer function\n", " if print_variables:\n", " print('Process TF: ', G)\n", " print('Controller TF: ', G_c)\n", " print('Closed-Loop TF: ', sys)\n", " return sys, T" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Process TF: \n", "1\n", "-\n", "s\n", "\n", "Controller TF: \n", "s + 1\n", "-----\n", " s\n", "\n", "Closed-Loop TF: \n", " s^3 + s^2\n", "---------------\n", "s^4 + s^3 + s^2\n", "\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Define our TF parameters \n", "K_p = 1\n", "tau_I = 1\n", "T = np.linspace(0,12,1000) # Time scale of the process, we'll use 12 seconds\n", "sys, T = tf(1,1,print_variables=True)\n", "\n", "# Generate a step response\n", "t, u = control.step_response(sys,T=T)\n", "\n", "# Plot\n", "plt.figure(1, figsize=(10,5))\n", "plt.xlabel('Time')\n", "plt.ylabel('Output')\n", "plt.plot(t,u)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks good, now let's make the plot interactive using the slider. We'll first need to import some libraries from ipywidgets." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": false }, "outputs": [], "source": [ "# Libraries you need for a simple slider\n", "from ipywidgets import interactive\n", "from ipywidgets import Button\n", "from IPython.display import display\n", "import warnings\n", "warnings.filterwarnings('ignore') #suppress all warnings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we need to define a function that we want to manipulate with our sliders. In our case, we want to manipulate the plot with 2 handles, $K_p$ and $\\tau_I$." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "65d6ac7611764adba264ba668dd17dfe" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def interactive_function(K_p, tau_I):\n", " # The transfer function we defined earlier\n", " sys, T = tf(K_p, tau_I)\n", " \n", " # Generate step response, step_response returns 2 values: t (time) and u (output)\n", " t, u = control.step_response(sys,T=T)\n", " \n", " # Plotting\n", " plt.figure(1, figsize=(10,5))\n", " plt.xlabel('Time')\n", " plt.ylabel('Output')\n", " plt.plot(t,u)\n", " plt.show()\n", "\n", "# ipywidgets to create sliders \n", "interactive_plot = interactive(interactive_function, K_p=(0.1, 5), tau_I=(0.05,10))\n", "output = interactive_plot.children[-1]\n", "interactive_plot" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 2 }