I thought today I would whip up a quick post regarding Jupyter Notebooks and how to download, install and use various “addons” that I like using and find more than just a little bit useful. Among other things I’ll show how to use the “jupyter-themes” module to change and manipulate the basic theme and styling of the overall notebook, I’ll show how to download and install the Jupyter Notebook extensions module giving access to a whole range of usefull goodies you can try out, and I’ll even show you how to use Jupyter widgets and how to embed URLs, PDFs, and Youtube videos directly into a notebook itself.
Below is the full list of contents I am going to cover, either all in this post or if it starts to get a bit long I may break it up over 2 posts to keep it a bit more manageable to read and digest.
- Jupyter-Themes Module
- Notebook Extensions
- Jupyter Widgets
- Qgrid
- Slideshow
- Embedding URLs, PDFs, and Youtube Videos
So onto our first entry – the jupyter-themes module. First of all we need to make sure we have the required module installed, and that is as easy as running the following command in a terminal window:
pip install jupyterthemes
Once we have the module correctly installed we can begin to use the relevant commands within ou notebook to change theme and styling elements.
Let’s look at an example below. Firstly we run the command that lists out all the available themes:
!jt -l
Available Themes: chesterish grade3 gruvboxd gruvboxl monokai oceans16 onedork solarizedd solarizedl
So if we wanted to implement the “chesterish” theme, for example, we would just run the code in the cell as shown in the animated screen grab below.

You can see the theme changes from the default light theme, to a dark theme. Great, at least we know it’s working!
You may have noticed however that when the new theme is set, there are a few things that seem to disappear, things that we may find useful to keep around – for example the toolbar at the top and the name of the notebook!
The module has a whole array of options which can be set which control the behaviour of all these things and more. I wont copy them all out again as they are available to look up on the official Github page for the module. This can be found here https://github.com/dunovank/jupyter-themes
One set up that I like to use can be created using the following command – just run it in a notebook cell, save the notebook and then refresh the browser and it should appear correctly.
!jt -t onedork -fs 95S -altout -tfs 14 -nfs 115 -cellw 90% -T -cursc r -cursw 5 -dfs 8 -N
You should now have a notebook that looks as follows, and we can see the top toolbar has reappeared, along with the notebook name in the top left and the respective “environment” that the notebook is being run in at the top right. You may notice a bunch of other toolbar icons and options that you haven’t seen before, but more on them later!

One thing to note however at this point is that although we have successfully altered our overall theme, the plotting theme still needs to be changed also to match out new style. If we were to currently plot a pandas DataFrame it would appear as follows:
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline Fs = 8000 f = 5 sample = 8000 x = np.arange(sample) y = np.sin(2 * np.pi * f * x / Fs) df = pd.DataFrame({'sin': y}, index=pd.date_range(start='01/01/2000', periods=sample, freq="D")) df['sin'].plot() plt.show()

That doesn’t look great at the moment. So let us run the relevant command to fix it and run the plot again:
# import jtplot submodule from jupyterthemes from jupyterthemes import jtplot # currently installed theme will be used to # set plot style if no arguments provided jtplot.style() df['sin'].plot() plt.show()

That looks much better! There are again a whole range of options that can be set using the “jtplot.style()” and passing various arguments. Details of these options can be found on the Github homepage also.
We now move onto the second entry in our list, the Notebook Extensions. To ensure we have the correct and necessary packages installed, run the following line of code in a terminal:
pip install jupyter_contrib_nbextensions && jupyter contrib nbextension install
Once that has finished installing, if you then restart your Jupyter Notebook server, you will hopefully find that you are presented with a couple of new options that didn’t appear previously. For the purposes of this article I shall revert back to the default Notebook theme so as to be able to show screenshots that will match your screen more closely.
On the main entry page that opens up when you start the Jupyter Notebook server, you should now see an option for “Nbextensions”. If you select that option you will be presented with a list of available extensions, ready and waiting to be added to your notebook.
I wont go through all of them, but I will highlight a couple that I find partciluarly useful.
The first one I want to mention is the “Table of Contents”. As Notebooks become large and code is added and added, it can become pretty cumbersome to have to scroll up and down searching for the specific cell that you happen to be looking for at that time. And well, the cells can often start to look petty similar…it’s not an easy task to quickly locate and identify specific parts/cells of your notebook. Well, enter the “Table of Contents” – it “does what it says in the tin” and it creates a side window that lists out a full, selectable, hyperlinked table of contents.
The table is populated using entries that have been entered as markdown, using the “#” syntax to denote levels of hierarchy in the content section titles and headings.
Entering a title in a markdown cell as follows, for example:
# Title Top Level
Will generate a “top level” title/section heading. Addoing more “#” then allows you to create section headings that would sit on the “second level” and “third level” etc. I have demonstrated an example of this below:
# Title Top Level 1 ## Title Second Level 1 ### Title Third Level 1 ### Title Third Level 2 # Title Top Level 2 ## Title Second Level 2 ### Title Third Level 3 ## Title Second Level 3 ### Title Third Level 4
The above would create the following table of contents, and display in the markdown cell as shown below:

You can then use the table of contents in the top left to navigate around the notebook more easily and quickly when looking for a specific cell or notebook “section”. I have found it to be a Godsend to be honest…really like this extension.
The second extension I want to highlight is the “Hinterland” extension. This sets the notebook to suggest auto completes on every key stroke, rather than just when one presses “shift+tab”. Below is a screen grab of it in action.

The third extension I think is worth mentioning is the “Snippets Menu”. It allows you to store customised code snippets that can be readily accessed and entered into notebook cells using a quick drop-down menu selection method.
You can set your customised code snippets in the relevant option box as shown in the screen grabs below and as long as you have the correct box checked they will appear in your toolbar drop down as soon as the notebook is refreshed.


And finally, the last extension that I want to mention is “Autopep8”. It creates a toolbar button that formats and cleans up your code, according to PEP8 guidelines with a single click – great for cleaning up those cells where the code seemed to get away from you! 😉 Not that the code ever “get’s away from you” of course!
Try it out for yourself and see if you like it as much as I do.
Now onto Jupyter Widgets! The first step as always is to install the necessary library:
pip install ipywidgets
Once that finishes, you can activate widgets for Jupyter Notebook with:
jupyter nbextension enable --py widgetsnbextension
To import the ipywidgets library in a notebook, run:
import ipywidgets as widgets from ipywidgets import interact, interact_manual from IPython.core.display import display, HTML
For this part of the article I shall be using the data found in this file:
df = pd.read_excel('Financial-Sample.xlsx') df.head()

How can we view all entries with more than 1500 units sold? Here’s one way:
df.loc[df['Units Sold'] > 1500]
But if we want to show entries with more than 20,000 COGS, we have to write another line of code:
df.loc[df['COGS'] > 20000]
What if we could just rapidly change these parameters — both the column and threshold — without writing more code? Try this:
@interact def show_entries_more_than(column='COGS', x=20000): return df.loc[df[column] > x]

Let’s apply the same method but this time create an interactive chart that allows you to specify the width and height of the chart figure, the colour of the bars within the plot and whether or not the plot has a visible grid.
@widgets.interact_manual( color=['blue', 'red', 'green'], width=(5., 12.), height=(5., 12.)) def plot(width=9.,height=6., color='blue', grid=True): t = df['Gross Sales'] fig, ax = plt.subplots(1, 1, figsize=(width, height)) ax.bar(t.index, t, color=color) ax.grid(grid)

I think I will leave it here for now as the post is starting to get a bit on the long side – I’ll follow up reasonably swiftly with another post covering the second half of the list of extensions/add-ons outlined at the start of the post.
Until next time!