Jupyter notebooks are made up of cells. Each cell is an execution scope, which means that it will be executed as a single block of instructions. Cells know about variables defined in previous cells (above them) but not any cells below them.
There are a few different types of cells:
When you execute a cell, it will be rendered (Markdown) or run through Python (Code). In fact, this cell was a Markdown cell and is then rendered using Markdown formatting.
Esc
.Enter
When in command mode, you can get a quick list of shortcut commands by typing h
or going to Help->Keyboard Shortcuts
.
When in command mode:
M
converts the cell to Markdown.Y
converts the cell to Code.In a notebook, you can execute cells in any order, but typically you should execute them top-to-bottom. One of the nice things about cells is you can make many quick changes and re-evaluate a cell without needing to re-evaluate the entire notebook.
When in command mode, use the up/down arrows to move to cells above/below.
You will definitely want to learn a bit about Markdown. Fortunately, there is a link under Help ➟ Markdown
that will point you to some helpful resources.
Among some of the things you can do:
Create sections (#
), subsections (##
), subsubsections (###
)
Create quote blocks for text using a >
My famous quote
Display code (that won't be executed) enclosed in a single tick ` for in-line code fragments or in a section of triple ticks ``` for separate displayed fragments:
def display_hello():
print('hello there!')
Insert LaTeX equations by enclosing them in $
for inline equations: $\alpha=\frac{\beta}{\gamma}$ and $$
for displayed equations:
$$\vec{q}=-\lambda\nabla T$$
Note that not all LaTeX functionality is supported, however. More on LaTeX below.
![Image](path-or-url)
For example, to insert picture.png
from the img
directory adjacent to your notebook: ![Image](img/picture.png)
[displayed link text](http://www.my_url.com)
Tables are formed using | to separate columns and ---
to indicate header rows. For example,
Fruit | Vegetable
------- | ---------
Banana | Pea
Kiwi | Carrot
displays:
Fruit | Vegetable |
---|---|
Banana | Pea |
Kiwi | Carrot |
You can also alter the cell alignment in a table:
Right-aligned | Centered | Left-aligned |
---|---|---|
Use a trailing : for right-aligned. |
Use leading and trailing : for centered |
Use leading : for left-aligned |
Republican | Sane | Democrat |
If you want to display data from Python in tabular format, you may want to use the pandas library.
You can link to any section heading as follows:
[link text to display](#heading-text)
For example, here is a link to the executing cells section above.
The heading text is case sensitive, and spaces should be replaced with dashes.
In addition to Markdown, you can use any HTML commands in a notebook (at least in markdown mode).
LaTeX is a powerful typesetting language in its own right, but a subset of LaTeX is supported in Jupyter.
If you are learning LaTeX, here is a cheat sheet that you may find useful.
Built-in to Jupyter notebooks you will find support for inline equations by encapsulating them in single $
and for displayed equations by encapsulating them in double $$
LaTeX | Displayed |
---|---|
\int_{\alpha}^{\beta} f(x) dx |
$\int_{\alpha}^{\beta} f(x) dx$ |
\frac{a}{b} |
$\frac{a}{b}$ |
\left( \frac{\partial f}{\partial x} \right) |
$\left( \frac{\partial f}{\partial x}\right)$ |
\vec{x} |
$\vec{x}$ |
\overline{abc} |
$\overline{abc}$ |
\int_a^b \underbrace{ \frac{1-x}{e^x}}_\mathrm{integrand} dx |
$\int_a^b \underbrace{ \frac{1-x}{\exp(x^2)}}_\mathrm{integrand} dx$ |
\mathsf{abcde} |
$\mathsf{abcde}$ |
\mathrm{abcde} |
$\mathrm{abcde}$ |
\boldsymbol{\alpha} |
$\boldsymbol{\alpha}$ |
LaTeX macros can be used to create shortcuts to simplify frequently used, complex expressions. Put them at the top of your notebook in a markdown cell and they will be available in any later markdown cell. Here are some examples: $\def\del#1#2{\frac{\partial#1}{\partial#2}}$ $\def\d#1#2{\frac{\mathrm{d}#1}{\mathrm{d}#2}}$ $\newcommand{\Ls}{\mathcal{L}_\sigma}$ $\def\D#1#2{\frac{\mathrm{D}#1}{\mathrm{D}#2}}$
Macro definition | Example Usage | Example Output |
---|---|---|
$\def\del#1#2{\frac{\partial#1}{\partial#2}}$ |
$\del{f}{x}$ |
$\del{f}{x}$ |
$\def\d#1#2{\frac{\mathrm{d}#1}{\mathrm{d}#2}}$ |
$\d{f}{x}$ |
$\d{f}{x}$ |
$\def\D#1#2{\frac{\mathrm{D}#1}{\mathrm{D}#2}}$ |
$\D{f}{x}$ |
$\D{f}{x}$ |
$\newcommand{\Ls}{\mathcal{L}_\sigma}$ |
$\Ls$ |
$\Ls$ |
If you install the nbextensions package then you get support for a few additional LaTeX features, including:
equation
environment for numbered equations:\begin{equation}
a = b + c \label{eq:my special equation}
\end{equation}
To disable numbering, put `\nonumber` after the equation. That is basically equivalent to putting the equation within double `$$`:
$$ a = b + c $$
align
environment for aligned (and numbered) equations:\begin{align}
a &\rightarrow b + c \\
c + d &\rightarrow e \\
\end{align}
This produces equations aligned at the `&` symbol. These equations are also numbered and can be labeled.
\ref{}
command and supply the label you created:\ref{eq:my special equation}
One of the great things about Jupyter is the ability to intersperse documentation (Markdown) with code that runs interactively and generates results.
We'll next consider a few useful things that you will need to know to get started in Python
In python, a function is defined using the def
keyword. For example, we could create a function add
def add( x1, x2 ):
return x1+x2;
The colon at the end of the first line, which indicates that the body of the function (indented) comes next.
To use this, we can call our add
function:
add( 5, 6 )
11
x = 3.14; y = 10;
z = add( x, y );
print(z)
13.14
print( add( 1, add(2,3) ) )
6
Python has a vast number of libraries to simplify many tasks. Among those that you will probably use regularly:
The first step in using a library is to tell Python that you want it. This is done using the import
command:
# import the numpy library and alias it to np. numpy provides linspace like matlab.
# It also provides constants like pi and functions like sin, cos, etc.
import numpy as np
x = np.linspace( 0, 2*np.pi ) # create an array spaced from 0 to 2*pi.
y = np.sin(x)
z = y**2
Python has vast plotting capabilities that can be a bit overwhelming. Frequently, we simply want to plot basic 1D functions, which is accomplished through matplotlib's pyplot package:
# note that this cell uses results defined in the cell above (x and z)
import matplotlib.pyplot as plt
plt.plot( x, np.sin(x), 'k', label='sin' ) # label is what the legend will show.
plt.plot( x, np.cos(x), 'r', label='cos' )
plt.plot( x, np.tan(x), 'g' ) # no label = no legend entry
plt.plot( x, z, label='$\sin^2$' )
plt.title('sin, cos and tan') # title for the plot
plt.xlabel('x') # x-axis label
plt.ylabel('f(x)') # y-axis label
plt.legend() # show the legend
plt.grid() # show the grid on the plot
plt.ylim(-1,1) # set the y-axis range
plt.xlim(0,2*np.pi) # set the x-axis range
plt.show() # render the plot
You can get help on a Python command by typing it in a command cell and following it by ?
then evaluating the cell:
import numpy as np
np.linspace?
Widgets are a set of simple tools that enable powerful interactivity in a notebook.
There are a few building blocks necessary:
interact
functionimport numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
from ipywidgets import interact
import ipywidgets as widgets
# Create the function that we will call. It can take multiple arguments if necessary.
def plot_it(f,w):
t = np.linspace(0,2,500)
if w=='sin':
plt.plot( t, np.sin(np.pi*f*t) )
elif w=='cos':
plt.plot( t, np.cos(np.pi*f*t) )
elif w=='tan':
plt.plot( t, np.tan(np.pi*f*t) )
plt.ylim([-4,4])
plt.xlabel('t',fontsize=16)
plt.grid()
plt.show()
# create our widgets.
fwidget = widgets.IntSlider(min=0,
max=8,
value=1,
description='Frequency:')
which = widgets.Dropdown(options=['sin','cos','tan'],
value='sin',
description='Function:')
# hook up the widget with the function
interact( plot_it, f=fwidget, w=which )
interactive(children=(IntSlider(value=1, description='Frequency:', max=8), Dropdown(description='Function:', o…
<function __main__.plot_it(f, w)>
There are many other things that you can do with widgets. See the documentation for more information.
%lsmagic
Available line magics: %alias %alias_magic %autoawait %autocall %automagic %autosave %bookmark %cat %cd %clear %colors %conda %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %pip %popd %pprint %precision %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode Available cell magics: %%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile Automagic is ON, % prefix IS NOT needed for line magics.
A line magic has a single %
prefix and applies to the given line of code only.
A cell magic has a double %%
prefix and applies to the whole cell below where it is found.
The timeit
magic is very useful when you want to time a section of code. For example:
import numpy as np
A = np.random.rand(50,50) # a large matrix
%timeit np.linalg.det(A) # calculate the determinant
19.4 µs ± 178 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
As you can see from the output, timeit
runs the cell/line several times to get a decent average time, and also reports the variability in the runtime.
The who
and whos
magics provide information about the variables defined in the notebook similar to their Matlab counterparts:
%whos
Variable Type Data/Info ---------------------------------------- A ndarray 50x50: 2500 elems, type `float64`, 20000 bytes add function <function add at 0x7faaa218c700> fwidget IntSlider IntSlider(value=1, descri<...>tion='Frequency:', max=8) interact _InteractFactory <ipywidgets.widgets.inter<...>object at 0x7faaa30828e0> np module <module 'numpy' from '/Us<...>kages/numpy/__init__.py'> plot_it function <function plot_it at 0x7faa900d59d0> plt module <module 'matplotlib.pyplo<...>es/matplotlib/pyplot.py'> rcParams RcParams _internal.classic_mode: F<...>: 0.6\nytick.right: False which Dropdown Dropdown(description='Fun<...>os', 'tan'), value='sin') widgets module <module 'ipywidgets' from<...>/ipywidgets/__init__.py'> x ndarray 50: 50 elems, type `float64`, 400 bytes y ndarray 50: 50 elems, type `float64`, 400 bytes z ndarray 50: 50 elems, type `float64`, 400 bytes
There are a few techniques to use in debugging a notebook:
print()
statements in to see what your code is doing.%who
or whos
cell magics. This will tell you what variables are currently defined.%%debug
cell magic to the beginning of a code cell. This will produce a terminal prompt at the bottom of the cell that allows you to enter python commands (like print
, etc.) without needing to rerun the whole cell.