Interactivity in python through Jupyter Lab

NodeJS and IpyWidgets need to be installed in order to use interactivity through Jupyter Lab. Such interactivity cannot be achieved through spyder. Interactive plots can be immensely useful for quickly seeing the effect of some critical parameters on the output of a certain piece of code.

In [1]:
import numpy as np;
import matplotlib.pyplot as plt;
plt.rcParams.update({"text.usetex":True});
%config InlineBackend.figure_format = "svg"
from ipywidgets import interactive

Let's begin by interactively plotting $\sin(2\pi k x)$. For this we will encapsulate the plotting sequence so that we need to pass the variables/parameters which we wish to interact with. Later, we can call the interactive function. Lastly, we need to simply show the widget. In this case, the widget is w.

In [2]:
def plot_sin(k=1, r=20):
    #k = 1;
    x = np.linspace(0, 2*np.pi*k, r)
    y = np.sin(x)
    plt.plot(x, y);

w = interactive(plot_sin, k=(0.1, 10, 0.05), r=(20, 200, 5));
w

We can now re-do the fixed point iterations example using interactivity. In the example below, interactivity is used to change the initial condition for the FPI and the number of iterations to be done.

In [3]:
def find_fixed(x0 = 2., Niter = 20):
    def fx(x):
        return np.log(3) + 2*np.log(x);

    def perform_iterations(x0, Niter):
        x = np.zeros(Niter); # Initialization
        x[0] = x0;
        for i in np.arange(1,Niter):
            x[i] = fx(x[i-1]);
        return x

    x = perform_iterations(x0, Niter);
    plt.plot(np.arange(0, Niter), x);

w = interactive(find_fixed, x0=(-2, 5, 0.05), Niter =(5, 50,1))
w

In the example below, we interact with the Cobweb plot wherein the initial guess and number of iterations can be changed through the sliders.

In [4]:
def cobweb(xg=2.0, Niter = 5):

    
    x = np.zeros(Niter);


    def fx(x):
        return np.log(3) + 2*np.log(x);

    xp = np.linspace(0.2, 5, 100);
    yp = fx(xp);
    plt.plot(xp, yp, label='$\\ln 3 + 2\\ln x$');
    plt.plot(xp, xp, label='$y = x$');
    plt.legend(fontsize=16);
    plt.xlabel("$x$", fontsize=16);
    plt.ylabel("$x, f(x)$", fontsize=16);
    plt.xticks(fontsize=16); plt.yticks(fontsize=16);
    ax = plt.gca(); ax.set_aspect(0.6);

    for i in np.arange(1, Niter):
        xn = fx(xg);
        plt.plot(xg, fx(xg), 'ok', markerfacecolor='black', markersize=2);
        x2 = xn; y2 = x2;
        plt.plot(x2, y2, 'ok', markerfacecolor='black', markersize=2 );
        plt.arrow(xg, fx(xg), x2-xg, y2-fx(xg), length_includes_head=True, linewidth=0.7, color='b');
        plt.arrow(x2, y2, x2-x2, fx(x2)-y2, length_includes_head=True, linewidth=0.7, color='r');
        xg = xn;

w = interactive(cobweb, xg = (0.5, 5, 0.1), Niter= (2, 20));
w