Makoto Yamashita : Notes

Data visualization with Jupyter

If you want to experiment with numerical simulation with interactive visualization, I recommend python libraries for scientific computation in the JupyterLab or Jupyter Notebook environments. They offer read-evaluation-print loop (REPL) for python, and allow (almost) seamless integration with graphics, interface elements like slider and button for modifying parameters of computation, and commenting in markdown format. This allows you to combine the code, its output, and the commentary all in one place.

Preparation

You need to have: JupyterLab or Jupyter Notebook environment

You also need to install ipympl for interactive presentation. Install it from Environments section of Anaconda Navigator, or execute

conda install -c conda-forge ipympl

in the terminal. Then include the magic command %matplotlib widget in a notebook cell before plot commands.

Plotting basics

The main library for plotting is matplotlib.pyplot. Import it as

import matplotlib.pyplot as plt

in your Jupyter Notebook. To draw graphs, you first need to activate a “canvas” by

fig, ax = plt.subplots()

Then you can draw into it using functions like plot (line / marker plot), hist (histogram), etc.

Typically, you combine pyplot with the numpy library. For example, you can plot the graph of a function by:

import numpy as np

fig, ax = plt.subplots()
xvar = np.linspace(-2, 2, 100)
ax.plot(xvar, np.sqrt(4 - xvar**2)*2/(np.pi * 4))

Under the hood, linspace produces an array object, and arithmetic operations like 4 - xvar**2 or numpy functions like numpy.sqrt transform that array. Then plot acts on a pair of such arrays representing the x- and y-coordinates of points on the graph to produce the plot. If you want to plot a more complicated function, you can define it as a separate function and transform the input array (x-coordinates) using list comprehension. The following example produces a similar plot of semicircular distribution as above, but allows the x-coordinate outside of the radius where the y-coordinate should be 0.

def myfunc(input_val):
    """Compute semicircular distribution of radius 2."""
    res = 0
    if abs(input_val) < 2:
        res = pow(4 - input_val**2, 0.5) * 2 / (3.1415 * 4)
    return res

fig, ax = plt.subplots()
xvar = np.linspace(-3, 3, 100)
ax.plot(xvar, [myfunc(x) for x in xvar])

For histograms, you need to specify “bins” of the input values as an array of numbers. For example, you can count numbers between 0 and 8 in the num_list array, classified by the bins of width 1, using

HIST_BINS = np.arange(0, 9, 1) # stop value (second argument) should be bigger than 8

fig2, ax2 = plt.subplots()
ax2.hist(num_list, bins=HIST_BINS)

Interactive plot

To animate plots, you can use matplotlib.animation library. The main functions are FuncAnimation and ArtistAnimation. FuncAnimation calls a call-back function to update the frame. For example, the following code will show an animation of the graph for y = sin(x) with increasing x-range.

fig, ax = plt.subplots()
# generate x- and y-coordinates of points in the graph
xvar = np.linspace(0,1,100)
yvar = np.sin(xvar)
# return value of plat is an array of Line2D objects
# retain the first (and only) one in in this list to manipulate the data
grph = ax.plot(xvar, yvar)[0]

def update_func(frame_num):
	# Updates the frame
	# grph is the Line2D object in the current plot conetxt
	# update its data to contain the first frame_num points of the plot
	grph.set_xdata(xvar[0:frame_num])
	grph.set_ydata(yvar[0:frame_num])
	return [grph]

anim = anm.FuncAnimation(fig, update_func, 100, repeat=True, blit=True)

ArtistAnimation works with a list of pre-constructed images (given by Artist objects). For example, hist function returns Artist objects in its output, that you can use in ArtistAnimation. See the sample code below for details.

In order to have interactive controls for parameters, you can use the interactive function from the ipywidgets library. Import it by

from ipywidgets import interact

To use it, prepare a drawing routine as a function with one argument to change (say draw_func(param)), and call interact(draw_func, param=(min_val, max_val)).

Download sample: Jupyter Notebook file

Preview: